JavaScript Date Methods Table
| Method | Returns | Field note |
|---|---|---|
new Date() | Current moment | Called with a string, parsing is implementation-flavored - prefer ISO format |
Date.now() | Milliseconds since epoch | The cheapest timestamp - no object allocation |
getFullYear() / getDate() | Numbers | getDate is day-of-month; getDay (next row) is weekday |
getDay() | 0-6, Sunday = 0 | The off-by-one trap: JS weekday starts Sunday, ISO starts Monday |
getMonth() | 0-11, January = 0 | The classic bug: never pass getMonth() into a 1-based API without +1 |
getHours() / getMinutes() | Numbers, local time | A whole getUTC* family exists for UTC reads |
getTime() | Milliseconds since epoch | The reliable comparison and arithmetic form |
toISOString() | UTC string | Always UTC - the source of the wrong-day bug when shown to local users |
toLocaleDateString(locale) | Localized date string | Pass a locale and options - never rely on the host default |
setDate(getDate() + 7) | Mutates the date | Add a week safely - rollover across months is handled |
Date.parse(s) | Milliseconds | ISO strings only, per spec; other formats are a minefield |
new Date(y, m, d) | Local-date constructor | Month is 0-based here too; two-digit years map to 1900+ |
JavaScript's Date object is one API with two personalities: a millisecond counter wearing a calendar costume. The methods either read the counter (getTime, Date.now) or project it onto a local calendar (getFullYear, getMonth) - and almost every date bug is a mixup between the two layers.
Bottom line: three traps cause nearly all of it. Months are 0-based - getMonth() returns 0 for January, and the constructor agrees, so new Date(2026, 1, 3) is February 3rd. getDay() returns the WEEKDAY (0 = Sunday), not the day of month - that is getDate(). And toISOString() converts to UTC before formatting, which shows the wrong day to anyone west of Greenwich after midnight.
The honest part: the arithmetic layer is the reliable one. Date.now() for timestamps, getTime() for comparisons and differences, setDate(getDate() + 7) for calendar math that correctly rolls over months and years. Formatting for humans belongs to toLocaleDateString with an explicit locale and options - never to hand-rolled getMonth-plus-one string surgery.
How to use
- Find the intent - read, compare, arithmetic, or format; each row notes which personality it belongs to.
- Check the trap notes before writing: the 0-based month and the getDay/getDate swap account for most production bugs.
- Format for humans at the edge only: toLocaleDateString('en-US', { month: 'long', day: 'numeric' }) and friends - never string-slice an ISO output for display.
Frequently asked questions
Why does my month show one month earlier?
Because JavaScript months are 0-based: January is 0, December is 11. getMonth() returns that raw index, and the constructor agrees - new Date(2026, 5, 15) is June 15, not May 15. The fix is presentation-layer: months[m] lookup arrays or toLocaleDateString with the month option. The deeper rule: pass 1-based month numbers through an API boundary and you have invented an off-by-one that will surface in June.
What is the difference between getDate and getDay?
getDate() returns the day of the month (1-31); getDay() returns the day of the WEEK (0-6, Sunday first). The one-letter difference plus the 0-based weekday makes getDay the most misread method in the standard library - code that checks date.getDay() === 15 is waiting for a date that never comes. ISO 8601 counts weekdays from Monday (1-7), so converting between the two conventions needs the (getDay() + 6) % 7 shift.
Why does toISOString show the wrong day?
Because it converts to UTC before formatting. A timestamp of 2026-03-05 23:30 in New York (UTC-5) is 2026-03-06 04:30 in UTC - toISOString prints March 6th to a user whose calendar says March 5th. The method is correct and the display is wrong: use toLocaleDateString with an explicit locale for anything a human reads, and keep toISOString for storage, APIs and keys where UTC is the point.
How do I add days to a date without breaking month boundaries?
Let the object do the arithmetic: d.setDate(d.getDate() + 7) rolls across month and year boundaries correctly because the method normalizes overflow. Adding milliseconds (getTime() + 7 * 86400000) is also exact but drifts across DST changes - the calendar methods are the safe form for date math. For differences, subtract two getTime() values and divide: Math.round((b - a) / 86400000) gives whole days resilient to partial-hour offsets.