In short
JavaScript has built-in tools for time. In this lesson you will learn to work with dates using the Date object, format them nicely, and run code later with setTimeout and setInterval. How to create a date in JavaScript A Date object stores one moment in time.
JavaScript has built-in tools for time. In this lesson you will learn to work with dates using the Date object, format them nicely, and run code later with setTimeout and setInterval.
How to create a date in JavaScript
A Date object stores one moment in time. new Date() with no arguments gives you right now. You can also create a specific date in a few ways:
const now = new Date();
console.log(now);
// Output (yours will differ): Thu Oct 01 2026 09:30:12 GMT+0100 (Western European Summer Time)
const birthday = new Date(2026, 0, 15);
console.log(birthday.toDateString());
// Output: Thu Jan 15 2026
const meeting = new Date("2026-03-20T14:30:00");
console.log(meeting.getHours(), meeting.getMinutes());
// Output: 14 30
With numbers, the order is year, month, day (and optionally hours, minutes, seconds). Be careful: months start at 0, so 0 is January and 11 is December. Days of the month start at 1 as normal. With a string, use the ISO format YYYY-MM-DDTHH:mm:ss, which every browser understands.
Common mistake: Writing
new Date(2026, 1, 15)and expecting January 15. Month1is February. This trips up almost everyone at least once.
Getting parts of a date
Date objects have "getter" methods to read each part:
| Method | Returns |
|---|---|
getFullYear() | The year, e.g. 2026 |
getMonth() | The month, 0 to 11 |
getDate() | The day of the month, 1 to 31 |
getDay() | The day of the week, 0 (Sunday) to 6 (Saturday) |
getHours(), getMinutes(), getSeconds() | The time parts |
getTime() | Milliseconds since 1 January 1970 (UTC) |
const order = new Date(2026, 0, 15, 9, 5);
const weekdays = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
console.log(order.getFullYear());
// Output: 2026
console.log(order.getMonth() + 1);
// Output: 1
console.log(weekdays[order.getDay()]);
// Output: Thu
console.log(`${order.getHours()}:${String(order.getMinutes()).padStart(2, "0")}`);
// Output: 9:05
We add 1 to the month for a human-friendly number, and use padStart so the minutes show as 05, not 5.
Formatting dates with toLocaleDateString and Intl.DateTimeFormat
Building date strings by hand is tiring, and every country writes dates differently. The browser can do it for you. toLocaleDateString() takes a locale (a language and region code, like "en-US" or "de-DE") and options.
const launch = new Date(2026, 0, 15);
console.log(launch.toLocaleDateString("en-US", { weekday: "long", year: "numeric", month: "long", day: "numeric" }));
// Output: Thursday, January 15, 2026
console.log(launch.toLocaleDateString("de-DE", { weekday: "long", year: "numeric", month: "long", day: "numeric" }));
// Output: Donnerstag, 15. Januar 2026
const short = new Intl.DateTimeFormat("en-GB", { dateStyle: "medium" });
console.log(short.format(launch));
// Output: 15 Jan 2026
const timeOnly = new Intl.DateTimeFormat("en-US", { timeStyle: "short" });
console.log(timeOnly.format(new Date(2026, 0, 15, 18, 45)));
// Output: 6:45 PM
Intl.DateTimeFormat creates a reusable formatter. It is a good choice when you format many dates the same way, like every row in a table. If you leave out the locale (undefined), the browser uses the visitor's own language settings.
Date math basics
Because a date is really a number of milliseconds, you can subtract two dates. The result is a difference in milliseconds, which you can turn into days. To move a date forward, change one part with a "setter" like setDate(); JavaScript handles the month overflow for you.
const MS_PER_DAY = 1000 * 60 * 60 * 24;
const today = new Date(2026, 9, 1);
const christmas = new Date(2026, 11, 25);
const daysLeft = Math.round((christmas - today) / MS_PER_DAY);
console.log(`${daysLeft} days until Christmas`);
// Output: 85 days until Christmas
const trialStart = new Date(2026, 0, 15);
const trialEnd = new Date(trialStart);
trialEnd.setDate(trialEnd.getDate() + 30);
console.log(trialEnd.toDateString());
// Output: Sat Feb 14 2026
We use Math.round because daylight saving time can make one day 23 or 25 hours long. new Date(trialStart) makes a copy, so the original date stays unchanged.
Note: A newer, much friendlier date API called Temporal is arriving in browsers. It fixes many
Dateproblems, such as zero-based months and time zone confusion. Check browser support before you rely on it;Dateworks everywhere today.
Running code later: setTimeout, setInterval and clearInterval
setTimeout(fn, ms) runs a function once after a delay in milliseconds (1000 ms = 1 second). setInterval(fn, ms) runs it again and again at that interval. Both return an ID number, which you pass to clearTimeout() or clearInterval() to cancel.
console.log("Order placed");
const reminder = setTimeout(() => {
console.log("Don't forget to check your email!");
}, 2000);
// Change your mind? Cancel it before it runs:
// clearTimeout(reminder);
console.log("This line runs first");
Order placed
This line runs first
Don't forget to check your email!
The last line appears after two seconds. JavaScript does not stop and wait; it schedules the function and carries on.
Example: a countdown timer
<!DOCTYPE html>
<html lang="en">
<body>
<p>Offer ends in <strong id="timer">10</strong> seconds</p>
<button id="stop">Stop timer</button>
<script>
const timerText = document.querySelector("#timer");
let secondsLeft = 10;
const intervalId = setInterval(() => {
secondsLeft -= 1;
timerText.textContent = secondsLeft;
if (secondsLeft === 0) {
clearInterval(intervalId);
timerText.textContent = "0 - the offer has ended";
console.log("Countdown finished");
}
}, 1000);
document.querySelector("#stop").addEventListener("click", () => {
clearInterval(intervalId);
console.log(`Stopped with ${secondsLeft} seconds left`);
});
</script>
</body>
</html>
Countdown finished
Every second, the number goes down by one. At zero we call clearInterval so the timer stops; without it, the count would go into negative numbers. The button stops the timer early.
Tip: Timers are not perfectly exact. The browser may run them a little late, especially in background tabs. For a precise clock, calculate the time left from the end date on each tick instead of counting ticks.
Practice exercise
Show a live clock on a page. Every second, update a <p> with the current time formatted by Intl.DateTimeFormat with { timeStyle: "medium" }. Below it, show how many days are left until your next birthday.
Hint: Create the formatter once, outside setInterval, and call formatter.format(new Date()) inside it.
Key takeaways
new Date()gives the current moment; innew Date(year, month, day)the month starts at0.- Use getters like
getFullYear()andgetDay()to read parts of a date. - Format dates for people with
toLocaleDateStringorIntl.DateTimeFormat. - Subtracting dates gives milliseconds;
setDate()moves a date forward or back. setTimeoutruns code once later,setIntervalrepeats it, andclearIntervalstops it.