Dates are everywhere in web apps: order times, event countdowns, "posted 3 hours ago" labels, booking calendars and birthdays. JavaScript handles them with the built-in Date object, which stores a single moment in time, and the Intl API, which formats dates, numbers and currencies in the style of any country and language.
Dates are famously tricky in every programming language. Months are numbered from 0, time zones shift the hour, and "31 January plus one month" has no obvious answer. The good news is that a small set of patterns covers almost everything you'll need in everyday projects.
In this lesson you'll create dates, read and change their parts, add and subtract days, work out the difference between two dates, and format them nicely with toLocaleDateString and Intl.DateTimeFormat. You'll also use Intl.NumberFormat for prices, and learn about Temporal, the newer date API arriving in browsers.
Creating dates
| Code | Creates |
|---|---|
new Date() | The current date and time |
new Date("2026-03-14") | 14 March 2026 at midnight UTC (ISO format) |
new Date("2026-03-14T09:30") | 09:30 local time on 14 March 2026 |
new Date(2026, 2, 14) | 14 March 2026, local time (month 2 is March) |
new Date(0) | 1 January 1970 UTC, the "epoch" |
Date.now() | The current time as milliseconds since the epoch (a number) |
Internally a date is just a number: milliseconds since 1 January 1970 UTC. Use the ISO format YYYY-MM-DD for date strings; other formats such as "03/14/2026" are read differently by different browsers.
Reading and changing parts
| Get | Set | Notes |
|---|---|---|
getFullYear() | setFullYear(2027) | Four-digit year |
getMonth() | setMonth(0) | 0 = January, 11 = December |
getDate() | setDate(15) | Day of the month, 1 to 31 |
getDay() | not settable | Day of the week, 0 = Sunday |
getHours(), getMinutes() | setHours(9, 30) | Local time |
getTime() | setTime(ms) | Milliseconds since the epoch |
Setters handle overflow sensibly: setDate(32) in January moves to 1 February, and setDate(0) gives the last day of the previous month. That makes adding days easy: d.setDate(d.getDate() + 7).
Comparing dates and measuring time
Because dates are numbers underneath, you can compare and subtract them:
const start = new Date("2026-06-01");
const end = new Date("2026-06-15");
end > start; // true
const days = (end - start) / (1000 * 60 * 60 * 24); // 14Use getTime() to check equality: a.getTime() === b.getTime(), because a === b compares objects, not moments. For performance timing, performance.now() is more precise than Date.now().
Formatting with Intl
const d = new Date("2026-03-14T09:30");
d.toLocaleDateString("en-GB"); // "14/03/2026"
d.toLocaleDateString("en-US"); // "3/14/2026"
d.toLocaleDateString("en-GB", { weekday: "long", day: "numeric", month: "long" }); // "Saturday 14 March"
d.toLocaleTimeString("en-GB", { hour: "2-digit", minute: "2-digit" }); // "09:30"| Formatter | Example output |
|---|---|
new Intl.DateTimeFormat("de-DE", { dateStyle: "full" }) | Samstag, 14. März 2026 |
new Intl.NumberFormat("en-GB", { style: "currency", currency: "GBP" }) | £1,234.50 |
new Intl.RelativeTimeFormat("en", { numeric: "auto" }).format(-1, "day") | yesterday |
Pass undefined as the locale to use the visitor's own browser language.
JavaScript Dates Syntax
Date essentials
const now = new Date();
const d = new Date("2026-12-25");
d.getFullYear(); d.getMonth(); d.getDate(); d.getDay();
d.setDate(d.getDate() + 7);
const diffDays = (b - a) / 86400000;
d.toISOString();
d.toLocaleDateString("en-GB", { dateStyle: "medium" });
new Intl.NumberFormat("en-US", { style: "currency", currency: "USD" }).format(19.5);JavaScript Dates Summary
new Date()creates a date; internally it's milliseconds since 1970.- Months are 0 to 11 and
getDay()starts with Sunday as 0. - Setters roll over, so
setDate(getDate() + n)adds days safely. - Subtracting dates gives milliseconds; divide to get days or hours.
toLocaleDateStringandIntlformat dates, times and currencies for any locale.
JavaScript Dates Examples
Each example runs in the page. Edit the code and press Run to see what changes.
Reading the parts of a date
const d = new Date(2026, 6, 4, 18, 5);
const days = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
console.log("Year:", d.getFullYear());
console.log("Month index:", d.getMonth(), "(July)");
console.log("Day of month:", d.getDate());
console.log("Weekday:", days[d.getDay()]);
console.log("Time:", `${d.getHours()}:${String(d.getMinutes()).padStart(2, "0")}`);
console.log("ISO:", d.toISOString().slice(0, 10));Line-by-line explanation
- Line 1Month 6 is July, because months start at 0.
- Line 2An array turns the weekday number into a name.
- Line 8
padStartadds a leading zero to the minutes. - Line 9The ISO string is in UTC, so the day can differ from local time late at night.
Adding days and counting down
function addDays(date, n) {
const copy = new Date(date);
copy.setDate(copy.getDate() + n);
return copy;
}
const order = new Date(2026, 0, 29);
const delivery = addDays(order, 5);
console.log("Delivery:", delivery.toDateString());
const holiday = new Date(2026, 11, 25);
const today = new Date(2026, 11, 1);
const msPerDay = 1000 * 60 * 60 * 24;
const daysLeft = Math.round((holiday - today) / msPerDay);
console.log(`${daysLeft} days until the holiday`);Line-by-line explanation
- Line 2Copy the date first, so the original isn't changed.
- Line 3Adding 5 days to 29 January rolls over into February.
- Line 14Subtracting gives milliseconds; dividing turns them into days.
Formatting for different countries
const d = new Date(2026, 2, 14, 9, 30);
console.log(d.toLocaleDateString("en-GB"));
console.log(d.toLocaleDateString("en-US"));
console.log(d.toLocaleDateString("en-GB", { weekday: "long", day: "numeric", month: "long", year: "numeric" }));
console.log(new Intl.DateTimeFormat("fr-FR", { dateStyle: "full", timeStyle: "short" }).format(d));
const price = 1234.5;
console.log(new Intl.NumberFormat("en-GB", { style: "currency", currency: "GBP" }).format(price));
console.log(new Intl.NumberFormat("de-DE", { style: "currency", currency: "EUR" }).format(price));
const rtf = new Intl.RelativeTimeFormat("en", { numeric: "auto" });
console.log(rtf.format(-1, "day"), "|", rtf.format(3, "week"));Line-by-line explanation
- Lines 3 to 4The UK puts the day first; the US puts the month first.
- Line 5Options choose exactly which parts to show and how.
- Line 6The same date in French, with the time.
- Lines 9 to 10Currency formatting adds symbols and separators for each country.
- Lines 12 to 13Relative times such as "yesterday" and "in 3 weeks".
Common JavaScript Dates Mistakes
Forgetting months start at 0
new Date(2026, 12, 25); // January 2027, not Decembernew Date(2026, 11, 25); // December
new Date("2026-12-25"); // or use an ISO stringComparing dates with ===
new Date("2026-01-01") === new Date("2026-01-01"); // false: two objectsnew Date("2026-01-01").getTime() === new Date("2026-01-01").getTime(); // trueChanging the original date by accident
function nextWeek(d) { d.setDate(d.getDate() + 7); return d; } // changes dfunction nextWeek(d) { const c = new Date(d); c.setDate(c.getDate() + 7); return c; }Date objects are mutable; copy them before changing.
JavaScript Dates in Real Projects
Dates in real apps
Booking sites calculate nights between check-in and check-out by subtracting dates. Social networks show "2 hours ago" with relative time formatting. Shops format prices with Intl.NumberFormat so the same code shows £, € or $ correctly. Libraries such as date-fns and Day.js add helpers, and the new Temporal API, now arriving in browsers, offers immutable dates and proper time zone support.
JavaScript Dates Exercises
Answer each one and check it instantly. If you get stuck, open the hint before the answer.
Get the four-digit year from a date.
const d = new Date("2026-05-20");
console.log(d.());
getFullYear() returns the year.What is logged?
const d = new Date(2026, 0, 31);
d.setDate(d.getDate() + 1);
console.log(d.getMonth(), d.getDate());What does getDay() return for a Sunday?
Which formats 9.5 as "$9.50"?
daysBetween(a, b) should return the whole number of days from date a to date b, and christmas(year) should return 25 December of that year. Fix both.
function daysBetween(a, b) {
return (b - a) / 1000;
}
function christmas(year) {
return new Date(year, 12, 25);
}
console.log(daysBetween(new Date(2026, 0, 1), new Date(2026, 0, 11)));
console.log(christmas(2026).toDateString());- Ten days apart
- Christmas is in December
- Same year
JavaScript Dates Quiz
5 questions to check what you learned.
What does new Date() give you?
- 1 January 1970
- An empty date
- The current date and time
- An error
What is a JavaScript date stored as internally?
- A string
- Seconds since the year 0
- An array of numbers
- Milliseconds since 1 January 1970 UTC
Which date string format is safest to parse?
- "03/14/2026"
- "2026-03-14"
- "14 March 26"
- "March the 14th"
How do you add 7 days to date d?
- d + 7
- d.addDays(7)
- d.setDate(d.getDate() + 7)
- d.getDate() + 7
Why store dates as UTC ISO strings?
- They mean the same moment everywhere, whatever the time zone
- They're shorter
- Browsers can't read local times
- JSON doesn't support numbers
JavaScript Dates Challenge
An order summary
Write orderSummary(ordered) where ordered is a Date:
- Work out
deliveryas 3 days afterordered, without changingordered - Format delivery with
toLocaleDateString("en-GB", { weekday: "long", day: "numeric", month: "long" }) - Return
`Arrives ${formatted}`
function orderSummary(ordered) {
}
console.log(orderSummary(new Date(2026, 2, 30)));- Rolls over into April
- Original date is unchanged
- Works in another month