SKU // 60

JavaScript Dates

Dates show up everywhere: due dates, timestamps, countdowns, "posted 3 days ago." JavaScript handles them with the built-in Date object. It is powerful but has a few famous traps, and this section walks through all of them.

Time Zones
Many outputs in this section depend on the time zone of the computer running the code. Examples here are shown for US Eastern time. If you are somewhere else, your hours may differ; the ideas are the same.

// What a Date Really Is

Under the hood, a Date is a single number: the milliseconds since midnight, January 1, 1970 (UTC). That moment is called the Unix epoch. Everything else, like months, weekdays, and time zones, is calculated from that number.

console.log(new Date(0).toISOString());   // "1970-01-01T00:00:00.000Z"
console.log(Date.now());                   // e.g. 1790913600000  (right now, in ms)

// Creating Dates: Four Ways

// 1. Right now
const now = new Date();

// 2. From parts: year, month, day, hours, minutes, seconds, ms
const meeting = new Date(2026, 9, 2, 14, 30);

// 3. From a date string
const launch = new Date("2026-10-02T14:30");

// 4. From a millisecond timestamp
const stamp = new Date(1790913600000);

console.log(meeting.toString());
Fri Oct 02 2026 14:30:00 GMT-0400 (Eastern Daylight Time)

Every constructor form

In all, there are 9 ways to call new Date(). The "from parts" form accepts anywhere from 2 to 7 numbers, always in the same order, and any parts you leave off default to their lowest value:

new Date()                               // now
new Date(dateString)                     // from a string
new Date(year, month)                    // the 1st of that month, midnight
new Date(year, month, day)
new Date(year, month, day, hours)
new Date(year, month, day, hours, minutes)
new Date(year, month, day, hours, minutes, seconds)
new Date(year, month, day, hours, minutes, seconds, ms)
new Date(milliseconds)                   // from a timestamp

A Date is a snapshot, not a running clock. const now = new Date(); records the moment that line ran. Five minutes later, now still holds the old time. To get the current time again, create a new Date.

// Trap 1: Months Start at Zero

When you build a date from parts, January is 0 and December is 11. Days of the month start at 1 as normal. This catches everyone at least once:

new Date(2026, 9, 2)    // October 2  (month 9 = October)
new Date(2026, 10, 2)   // November 2, not October!
new Date(2026, 11, 25)  // December 25
Watch out
Month indexes run 0 to 11, but day numbers run 1 to 31. When a date is off by exactly one month, this is almost always the cause.

// Trap 2: Date-Only Strings Are UTC

A string with just a date, like "2026-10-02", is treated as midnight in UTC, not your local time. In the Americas, that is still the previous evening:

console.log(new Date("2026-10-02").toString());
Thu Oct 01 2026 20:00:00 GMT-0400 (Eastern Daylight Time)

Add a time to make it local:

new Date("2026-10-02T00:00")   // midnight Oct 2, local time
new Date(2026, 9, 2)           // also midnight Oct 2, local time

// Trap 3: Dates Are Objects

const a = new Date(2026, 9, 2);
const b = new Date(2026, 9, 2);

console.log(typeof a);                     // "object"
console.log(a === b);                      // false  (two different objects)
console.log(a.getTime() === b.getTime());  // true   (same moment in time)
object false true

To compare two dates for equality, compare their getTime() numbers. The < and > operators do work directly on dates.

// Trap 4: One Number Is Milliseconds

You cannot leave out the month. With only one number, JavaScript does not read it as a year; it reads it as a millisecond timestamp:

console.log(new Date(2018).toISOString());        // not the year 2018!
console.log(new Date(2018, 0).toDateString());     // Jan 1, 2018
1970-01-01T00:00:02.018Z Mon Jan 01 2018

2018 milliseconds is just over two seconds past the epoch. Negative timestamps work too, counting backward from 1970: new Date(-100000000000) is in 1966.

// Trap 5: Two-Digit Years Mean 19xx

console.log(new Date(99, 11, 24).toDateString());
console.log(new Date(9, 11, 24).toDateString());
Fri Dec 24 1999 Fri Dec 24 1909

Years 0 to 99 are treated as 1900 to 1999, a leftover from the last century. Always write the full four-digit year.

// Overflow Rolls Over

A month above 11 or a day past the end of the month is not an error. The extra spills into the next month or year:

console.log(new Date(2018, 15, 24).toDateString());   // month 15 = 3 months into 2019
console.log(new Date(2018, 5, 35).toDateString());    // June 35 = July 5
Wed Apr 24 2019 Thu Jul 05 2018

This is annoying when it hides a typo, but very handy for date math. JS Date Set uses it to add days and months.

// Date Math: Subtracting Dates

Subtracting one date from another gives the difference in milliseconds. Divide to get days:

const today     = new Date(2026, 9, 2);
const christmas = new Date(2026, 11, 25);

const MS_PER_DAY = 1000 * 60 * 60 * 24;
const daysLeft = Math.round((christmas - today) / MS_PER_DAY);

console.log(`${daysLeft} days until Christmas`);
84 days until Christmas
Tip
Use Math.round, not Math.floor, when converting to days. A daylight saving change in between makes one day 23 or 25 hours long, which would otherwise knock the answer off by one.

// Invalid Dates

A string JavaScript cannot understand does not throw an error. It produces a Date that is broken:

const bad = new Date("next Tuesday");

console.log(bad.toString());          // "Invalid Date"
console.log(Number.isNaN(bad.getTime()));  // true: the way to test for it

// The Road Ahead

Date FormatsWhich strings to feed in, and how to display dates nicely
Date GetReading the year, month, weekday, hour...
Date SetChanging parts of a date, and adding days or months

// Quick Check

Which creates March 5, 2027?

  1. new Date(2027, 3, 5)
  2. new Date(2027, 2, 5)
  3. new Date(2027, 5, 3)
  4. new Date("2027-03-05") (in the Americas)
Show answer
B. Months start at 0, so March is 2. A is April 5. C is June 3. D is midnight UTC, which is still March 4 in the Americas.

What does this log?

const a = new Date(2026, 0, 1);
const b = new Date(2026, 0, 1);
console.log(a === b, a.getTime() === b.getTime());
Show answer
false true. Dates are objects, so === checks whether they are the same object. Compare their getTime() numbers to check for the same moment.

What does new Date(2030) create?

  1. January 1, 2030
  2. A date 2030 milliseconds after January 1, 1970
  3. An Invalid Date
  4. A SyntaxError
Show answer
B. With a single number, JavaScript reads it as a timestamp in milliseconds. You need at least a year and a month: new Date(2030, 0).

// Try It

  1. Click Open Playground and run it. Compare what each line gives you
  2. Create your next birthday from parts. Double-check the month index
  3. Compare new Date("2026-10-02") with new Date("2026-10-02T00:00")
  4. Calculate how many days are left until the end of the school year
// Video Walkthroughs
Last updated: Oct 10, 2026, 1:41 AM ET