Date.prototype.setMonth()
Sets the zero-based month of a date in local time and returns the new timestamp.
setMonth(monthValue)
setMonth(monthValue, dateValue)- Added in JavaScript ES1
Parameters
| Parameter | Type | Description |
|---|---|---|
$monthValue | number | An integer representing the month, 0 for January through 11 for December. Values outside 0–11 shift the year accordingly. |
$dateValueoptional | number= this.getDate() | An integer from 1 to 31 representing the day of the month. Defaults to the value returned by getDate(). |
Return value
numberThe new timestamp of the modified Date object in milliseconds since the epoch. Returns NaN if any parameter is NaN or coerces to NaN, in which case the Date is set to Invalid Date.
Changelog
- PHP Modern enginesLocal times that land in a DST gap or ambiguity resolve like Temporal's "compatible" disambiguation: the earlier instant is chosen when two exist, and gaps are crossed forward.
setMonth() writes the month onto an existing date in place, using the same zero-based numbering as the constructor: 0 is January, 11 is December. It returns the new timestamp, not the date.
Overflow is a feature
Values outside 0–11 roll into neighbouring years, which makes month arithmetic a one-liner: d.setMonth(d.getMonth() + 3) moves forward a quarter and crosses the new year correctly with no special case.
The end-of-month trap
The day-of-month is carried over unchanged and then overflows if the target month is too short. Start on 31 January, call setMonth(1), and you land on 2 March, not 28 or 29 February. Any "add one month" feature built naively on this will skip February for month-end subscriptions.
The fix is to set the day to 1 first, change the month, then clamp the day against the target month's real length — which you can get with new Date(year, month + 1, 0).getDate().
When to reach for it
- Stepping a report window forward or back by whole months.
- Rebuilding a date from a month dropdown.
- Normalizing a date to the start of its month.
Example
When to use it
- Advance a reporting period by one quarter
- Normalize a timestamp to the first day of its month
- Rebuild a date after a user picks a month from a dropdown
- Compute a renewal date a fixed number of months out
Frequently asked questions
Why does setMonth(1) give me March instead of February?
Because the current day-of-month is carried over first: if the date was the 30th or 31st, February cannot hold it and the excess rolls into March. Call setDate(1) before setMonth(), then set the day back with a clamp.
How do I add months to a date in JavaScript?
Call d.setMonth(d.getMonth() + n) — values above 11 or below 0 automatically adjust the year. To avoid the month-end overflow, set the day to 1 first, change the month, then clamp the day to the target month's length.
Is setMonth() zero-based?
Yes — January is 0 and December is 11, matching getMonth() and the Date constructor. Passing 12 does not error; it means January of the following year.
More examples
Add months safely
Setting the day to 1 before touching the month prevents the overflow, and the clamp pins 31 January to the last real day of February — 29 in a leap year, 28 otherwise. The third call shows the year rolling correctly.
function addMonths(date, n) {
const out = new Date(date);
const day = out.getDate();
out.setDate(1); // park on a day every month has
out.setMonth(out.getMonth() + n);
const lastDay = new Date(out.getFullYear(), out.getMonth() + 1, 0).getDate();
out.setDate(Math.min(day, lastDay));
return out;
}
console.log(addMonths(new Date(2024, 0, 31), 1).toDateString()); // Feb 29 2024
console.log(addMonths(new Date(2023, 0, 31), 1).toDateString()); // Feb 28 2023
console.log(addMonths(new Date(2024, 10, 15), 3).toDateString()); // Feb 15 2025Month boundaries for a report window
Stepping to the next month and then calling setDate(0) walks back to the final day without hard-coding month lengths. Leap February prints the 29th while the non-leap year prints the 28th.
function monthRange(d) {
const start = new Date(d);
start.setDate(1);
start.setHours(0, 0, 0, 0);
const end = new Date(start);
end.setMonth(end.getMonth() + 1);
end.setDate(0); // last day of the original month
return [start.toDateString(), end.toDateString()];
}
console.log(monthRange(new Date(2024, 1, 17))); // February 2024
console.log(monthRange(new Date(2023, 1, 17))); // February 2023
Discussion