Academic Block

Date & Time Get Certified

Working with dates and times is one of the more error-prone parts of everyday JavaScript. The built-in Date object gives you the tools to create, read, compare, and format dates — once you know its quirks.

Creating Dates

new Date() with no arguments gives you the current moment. You can also create a specific date by passing year, month, day (and optionally time), or by parsing a date string.

What this code does: This code shows several ways to create JavaScript Date objects: the current date and time, a specific date, a date with a specific time, and a date parsed from an ISO-style string.

const now = new Date();
console.log("Right now:", now);

// Year, month (0-indexed!), day
const specificDate = new Date(2024, 2, 15);
console.log("March 15, 2024:", specificDate);

// Year, month, day, hours, minutes, seconds
const withTime = new Date(2024, 2, 15, 14, 30, 0);
console.log("With a specific time:", withTime);

// Parsing an ISO date string
const parsed = new Date("2024-03-15T14:30:00");
console.log("Parsed from string:", parsed);

Watch out: the month argument is zero-indexed — 2 means March, not February. This trips up almost everyone at least once.

Reading Parts of a Date

A Date object has getter methods for every component — year, month, day, hours, and so on — all based on the browser’s local timezone by default.

What this code does: This code reads individual parts of a Date object, such as the year, month, day, weekday, hours, minutes, and the timestamp in milliseconds.

const date = new Date(2024, 2, 15, 9, 5, 0);

console.log("Full year:", date.getFullYear());
console.log("Month (0-indexed):", date.getMonth());
console.log("Day of month:", date.getDate());
console.log("Day of week (0 = Sunday):", date.getDay());
console.log("Hours:", date.getHours());
console.log("Minutes:", date.getMinutes());
console.log("Milliseconds since Jan 1, 1970:", date.getTime());

getDay() gives the day of the week (0 for Sunday through 6 for Saturday), while getDate() gives the day of the month — these two are easy to confuse.

Date Arithmetic

Date objects don’t have built-in “add days” methods. Instead, you read a part, add to it, and set it back. JavaScript automatically rolls the date over into the next month or year as needed.

What this code does: This code performs date arithmetic by adding days, adding months, and subtracting a year. JavaScript automatically adjusts the date when values roll into another month or year.

const today = new Date(2024, 2, 15);
console.log("Starting date:", today.toDateString());

// Add 10 days — JS rolls over into April automatically
const tenDaysLater = new Date(today);
tenDaysLater.setDate(tenDaysLater.getDate() + 10);
console.log("10 days later:", tenDaysLater.toDateString());

// Add 2 months
const twoMonthsLater = new Date(today);
twoMonthsLater.setMonth(twoMonthsLater.getMonth() + 2);
console.log("2 months later:", twoMonthsLater.toDateString());

// Subtract 1 year
const oneYearEarlier = new Date(today);
oneYearEarlier.setFullYear(oneYearEarlier.getFullYear() - 1);
console.log("1 year earlier:", oneYearEarlier.toDateString());

Notice new Date(today) is used to clone the original date before modifying it — calling .setDate() directly on today would mutate the original object in place.

Comparing Dates and Finding the Difference

Dates can be compared directly with < and >. Subtracting one date from another gives the difference in milliseconds, which you can convert into days, hours, or any other unit.

What this code does: This code compares two dates, calculates the number of days between them, and uses a reusable helper function to find the absolute difference between any two dates.

const deadline = new Date(2024, 5, 1);
const today = new Date(2024, 2, 15);

console.log("Is today before the deadline?", today < deadline);

const diffInMs = deadline - today;
const diffInDays = Math.round(diffInMs / (1000 * 60 * 60 * 24));
console.log("Days until deadline:", diffInDays);

function daysBetween(dateA, dateB) {
    const msPerDay = 1000 * 60 * 60 * 24;
    return Math.round(Math.abs(dateB - dateA) / msPerDay);
}

console.log("Days between (helper function):", daysBetween(today, deadline));

Formatting Dates for Display

Raw Date objects aren’t very readable. The built-in toLocaleDateString() and related methods give you locale-aware, human-friendly formatting without a library.

What this code does: This code demonstrates common date and time formatting methods, including the default string, ISO format, locale-specific date, detailed date, and locale-specific time.

const date = new Date(2024, 2, 15, 14, 30);

console.log("Default toString():", date.toString());
console.log("ISO format:", date.toISOString());
console.log("Locale date:", date.toLocaleDateString("en-US"));

console.log("Locale date, verbose:", date.toLocaleDateString("en-US", {
    weekday: "long",
    year: "numeric",
    month: "long",
    day: "numeric"
}));

console.log("Locale time:", date.toLocaleTimeString("en-US", {
    hour: "2-digit",
    minute: "2-digit"
}));

Quick Reference: Common Date Methods

Method Returns Notes
getFullYear() Four-digit year Prefer this over the deprecated getYear()
getMonth() 0–11 Zero-indexed — January is 0
getDate() 1–31 Day of the month
getDay() 0–6 Day of the week (0 = Sunday)
getTime() Milliseconds since Jan 1, 1970 Useful for comparisons and arithmetic
toISOString() ISO 8601 string (UTC) Great for storing / transmitting dates
toLocaleDateString() Locale-formatted string Best for displaying dates to users

Common Mistakes

  • Forgetting that months are zero-indexed
  • Mutating a shared Date object instead of cloning it first
  • Mixing up local time and UTC
  • Comparing dates with === instead of < / > or .getTime()
  • Manually building date strings instead of using locale-aware formatters

Best Practices

  • Store and transmit dates as ISO 8601 strings or timestamps
  • Use toLocaleDateString() / toLocaleTimeString() for anything shown to users
  • Clone a Date before mutating it if the original is still needed
  • Compare dates using .getTime() or relational operators, never ===
  • Consider a well-maintained library for complex timezone or recurring-event needs

Quick Summary

  • new Date() creates the current moment; remember that months are zero-indexed
  • Getter methods read individual parts of a date in local time
  • Date arithmetic works by reading a part, adding to it, and setting it back
  • Subtracting two dates gives a difference in milliseconds
  • toLocaleDateString() and toISOString() are the two main formatting methods

Try It Yourself

What this code does: This code combines reusable date functions to calculate days until a target date and to add business days while skipping Saturdays and Sundays.

function daysUntil(targetDate) {
    const now = new Date();
    const msPerDay = 1000 * 60 * 60 * 24;
    const diff = targetDate - now;
    return Math.ceil(diff / msPerDay);
}

function addBusinessDays(startDate, days) {
    const result = new Date(startDate);
    let added = 0;
    while (added < days) {
        result.setDate(result.getDate() + 1);
        const dayOfWeek = result.getDay();
        if (dayOfWeek !== 0 && dayOfWeek !== 6) {
            added++;
        }
    }
    return result;
}

const launchDate = new Date(2025, 0, 1);
console.log("Days until launch:", daysUntil(launchDate));

const start = new Date(2024, 2, 15);
const afterFiveBusinessDays = addBusinessDays(start, 5);
console.log("Start date:", start.toDateString());
console.log("5 business days later:", afterFiveBusinessDays.toDateString());
Tip: When a date bug shows up, check the month indexing and the local-vs-UTC distinction first — together they explain the vast majority of date-related bugs in JavaScript.

🧪 Test Your JavaScript Code

Edit the code on the left and click "Run Code" to see the console output on the right.

📝 JavaScript Code
👁 Console Output

Click "Run Code" to see the output here.

Ctrl + Enter to run code Esc to close