Utilities.formatDate with YYYY shows the wrong year
var d = new Date(2025, 11, 29); // Dec 29, 2025
Utilities.formatDate(d, 'America/New_York', 'YYYY-MM-DD'); // "2026-12-363" ← wrong
Utilities.formatDate(d, 'America/New_York', 'yyyy-MM-dd'); // "2025-12-29"
Why it happens
Utilities.formatDate uses Java SimpleDateFormat letters, not the YYYY-MM-DD you'd write in a spreadsheet:
| Letter | Means | You probably wanted |
|---|---|---|
YYYY | week-based year (flips early in late December) | yyyy |
DD | day of year (1–366) | dd |
mm | minutes | MM (month) |
hh | 1–12 hour | HH (0–23) |
The bug hides for most of the year, then breaks file names and reports in the last days of December. It shows up a lot in Rhino-era scripts — fix it while you migrate.
Time zones
Pass Session.getScriptTimeZone() (not the removed Session.getTimeZone()), or the spreadsheet's getSpreadsheetTimeZone() when formatting dates read from cells.
var ss = SpreadsheetApp.getActive();
Utilities.formatDate(date, ss.getSpreadsheetTimeZone(), 'yyyy-MM-dd');
How V8Shift handles it
Patterns containing YYYY/DD are rewritten to yyyy/dd (marked for review) and Session.getTimeZone() becomes Session.getScriptTimeZone().