Date.prototype.setDate()
Sets the day of the month in local time, rolling into adjacent months when the value is out of range.
setDate(dateValue)- Added in JavaScript ES1
Parameters
| Parameter | Type | Description |
|---|---|---|
$dateValue | number | An integer representing the day of the month. Values outside the month's range roll the date forward or backward into adjacent months. |
Return value
numberThe new timestamp of the modified Date object in milliseconds since the epoch. Returns NaN if dateValue is NaN or coerces to NaN, in which case the Date is set to Invalid Date.
Changelog
- PHP Modern enginesLocal times landing in a DST gap or ambiguity resolve like Temporal's "compatible" disambiguation, so a day step across a transition preserves the wall-clock time rather than the elapsed milliseconds.
setDate() writes the day of the month in place and returns the new timestamp. Its real value is the overflow behaviour: out-of-range values are not errors, they roll into neighbouring months, and that turns date arithmetic into one line.
The three idioms worth memorizing
d.setDate(d.getDate() + 30)— add 30 days, crossing month and year boundaries correctly.d.setDate(0)— jump to the last day of the previous month. Combined with stepping the month forward first, this is how you find a month's length without a lookup table.d.setDate(32)on a 31-day month — land on the 1st of the next month.
Negative values keep counting backwards: from 7 July, setDate(-50) reaches 11 May.
What trips people up
It mutates. setDate() changes the object you called it on and hands back a number, so anything else holding that same Date sees the change. Clone with new Date(d) before stepping.
It also works in local time, so adding a day across a daylight saving transition adds 23 or 25 hours of real time while keeping the wall clock identical. That is usually what a calendar wants and never what a timer wants — use setTime() for fixed-size shifts.
Example
When to use it
- Add or subtract a number of days for a due date
- Find the last day of any month without a lookup table
- Step through every day in a month for a calendar grid
- Roll a weekly reminder forward by seven days
Frequently asked questions
How do I add days to a date in JavaScript?
Call d.setDate(d.getDate() + n) — the overflow handling moves into the next month or year automatically, so no bounds checking is needed. Clone the date first with new Date(d) if you need to keep the original.
What does setDate(0) do?
It sets the date to the last day of the previous month, because day 0 is one day before the 1st. Combined with stepping the month forward first, it is the standard way to get the number of days in a month.
Why is my date one hour off after using setDate()?
setDate() works in local time, so stepping across a daylight saving transition keeps the wall-clock time and changes the elapsed milliseconds by an hour. Use setTime() with a fixed millisecond offset if you need exact 24-hour steps.
More examples
Length of any month
Stepping to the first of the following month and then calling setDate(0) walks back one day, which is always the last day of the month you asked about. Leap years fall out of it for free.
function daysInMonth(year, month) { // month is zero-based
const d = new Date(year, month + 1, 1);
d.setDate(0); // back to the last day of `month`
return d.getDate();
}
console.log(daysInMonth(2024, 1)); // 29 — leap February
console.log(daysInMonth(2023, 1)); // 28
console.log(daysInMonth(2024, 3)); // 30 — April
console.log(daysInMonth(2024, 0)); // 31 — JanuaryClone before stepping
The clone keeps the original due date intact, which a naive due.setDate(...) would destroy. The loop shows the rollover in action: after 29 February 2024 the cursor lands on 1 March.
const due = new Date(2024, 0, 20);
const reminder = new Date(due); // independent copy
reminder.setDate(reminder.getDate() - 3);
console.log(due.toDateString()); // Sat Jan 20 2024 — unchanged
console.log(reminder.toDateString()); // Wed Jan 17 2024
const week = [];
const cursor = new Date(2024, 1, 26);
for (let i = 0; i < 5; i++) {
week.push(cursor.getDate());
cursor.setDate(cursor.getDate() + 1);
}
console.log(week); // [ 26, 27, 28, 29, 1 ] — rolls into March
Discussion