# JavaScript Date: Working with Dates and Times in JS

Source: https://devdocs10.com/articles/javascript/js-dates  
By Murat Bo · Published 2026-06-26 · DevDocs10 (https://devdocs10.com)

JavaScript's `Date` object is the built-in way to work with dates, times, timestamps, and time zones. It is used for everything from showing a post's published time to scheduling reminders and measuring elapsed time.

> **Quick answer:** `Date` is the built-in JavaScript object for representing a specific moment in time. You create one with `new Date()`, then read or change values with methods like `getFullYear()`, `toISOString()`, and `getTime()`.

> **Difficulty:** Beginner
>
> **You'll understand this better if you know:** basic JavaScript variables, functions, and how objects store data and behavior.

## 1. What Is Date?

`Date` is JavaScript's standard object for representing points in time. Internally, a date value is stored as a number of milliseconds since the Unix epoch: midnight at the start of January 1, 1970, UTC.

- It can represent a specific instant, not just a calendar day.
- It stores time with millisecond precision.
- It can display values in local time or UTC.
- It includes parsing, formatting, and arithmetic methods.

That means a `Date` object is useful for both human-friendly calendar display and machine-friendly time calculations.

## 2. Why Date Matters

Nearly every application needs dates and times at some point. A shopping app may need delivery dates, a dashboard may show last-updated times, and a scheduling tool may compare two timestamps.

JavaScript's `Date` matters because it is available everywhere JavaScript runs, including browsers and Node.js. You do not need a library for basic date storage, comparison, or formatting.

At the same time, `Date` is also one of the most misunderstood built-in objects because time zones, parsing rules, and locale formatting can produce unexpected results. Learning the built-in behavior helps you avoid subtle bugs.

## 3. Basic Syntax

The most common way to create a date is with `new Date()`. You can create the current moment, a specific timestamp, or a date from a string.

### Create the current date and time

This creates a `Date` for the exact moment the code runs.

```javascript
const now = new Date();
```

@@BLOCK28@@

The month number is zero-based, so `0` means January and `11` means December.

```javascript
const independenceDay = new Date(2026, 6, 4);
```

@@BLOCK29@@

A timestamp is the number of milliseconds since the Unix epoch.

```javascript
const fromTimestamp = new Date(1719830400000);
```

Once you have a date, you can read parts of it with methods such as `getFullYear()`, `getMonth()`, `getDate()`, and `getHours()`.

## 4. Step-by-Step Examples

### Example 1: Get today's date and format it

This example creates a `Date` object for the current moment and prints a simple local date string.

```javascript
const today = new Date();

console.log(today.toDateString());
```

This is useful for quick display, though it is not ideal for custom formatting.

### Example 2: Read the individual parts of a date

Sometimes you need the year, month, and day separately.

```javascript
const date = new Date(2025, 0, 15);

const year = date.getFullYear();
const month = date.getMonth();
const day = date.getDate();

console.log(year, month, day);
```

Output (tested with Node 24.21.0):

```text
2025 0 15
```

Remember that `getMonth()` returns a zero-based month, so January is `0`.

### Example 3: Compare two dates

You can compare timestamps directly by converting each date with `getTime()`.

```javascript
const start = new Date(2025, 0, 1);
const end = new Date(2025, 0, 31);

if (end.getTime() > start.getTime()) {
  console.log("End is after start");
}
```

Output (tested with Node 24.21.0):

```text
End is after start
```

Because timestamps are just numbers, date comparisons are simple and reliable.

### Example 4: Format a date for display

The `toLocaleDateString()` method uses the user's locale to format a readable date.

```javascript
const eventDate = new Date(2025, 10, 5);

const formatted = eventDate.toLocaleDateString("en-US", {
  year: "numeric",
  month: "long",
  day: "numeric"
});

console.log(formatted);
```

Output (tested with Node 24.21.0):

```text
November 5, 2025
```

This produces a human-friendly string such as `November 5, 2025`.

## 5. Practical Use Cases

- Showing a post's published date in a blog or CMS.
- Calculating how many days remain until an event or deadline.
- Recording when a user last signed in or updated a profile.
- Checking whether an action happened before or after another event.
- Converting API timestamps into readable local times.
- Scheduling reminders, notifications, or background jobs.

In most projects, `Date` is used for both storage and display, but the best practice is usually to store timestamps or ISO strings and format them only when needed.

## 6. Common Mistakes

### Mistake 1: Forgetting that months are zero-based

JavaScript's date constructor treats months as `0` through `11`. New developers often pass `1` for January and get the wrong month.

**Problem:** This creates February 15, not January 15, because the month argument starts at zero.

```javascript
const wrong = new Date(2025, 1, 15);
console.log(wrong.toDateString());
```

Output (tested with Node 24.21.0):

```text
Sat Feb 15 2025
```

**Fix:** Use `0` for January, `1` for February, and so on.

```javascript
const correct = new Date(2025, 0, 15);
console.log(correct.toDateString());
```

Output (tested with Node 24.21.0):

```text
Wed Jan 15 2025
```

The corrected version works because it matches JavaScript's month indexing rules.

### Mistake 2: Comparing dates with `==` or `===`

Two different `Date` objects are different object references, even if they represent the same moment.

**Problem:** Reference comparison does not compare the actual time value, so these checks usually fail even when the dates look identical.

```javascript
const a = new Date(2025, 0, 1);
const b = new Date(2025, 0, 1);

console.log(a === b);
```

Output (tested with Node 24.21.0):

```text
false
```

**Fix:** Compare the timestamps with `getTime()` or `valueOf()`.

```javascript
const a = new Date(2025, 0, 1);
const b = new Date(2025, 0, 1);

console.log(a.getTime() === b.getTime());
```

Output (tested with Node 24.21.0):

```text
true
```

The corrected version works because timestamps compare the actual moment in time.

### Mistake 3: Assuming parsed date strings are always reliable

String parsing with `Date` can be inconsistent if the format is not ISO 8601 or otherwise well supported. Some strings may create an invalid date without an obvious error.

**Problem:** A date string can produce `Invalid Date`, and methods such as `getTime()` then return `NaN`.

```javascript
const parsed = new Date("15/01/2025");

console.log(parsed.toString());
console.log(parsed.getTime());
```

Output (tested with Node 24.21.0):

```text
Invalid Date
NaN
```

**Fix:** Use a reliable format such as ISO 8601, or build the date from numeric parts yourself.

```javascript
const parsed = new Date("2025-01-15T00:00:00Z");

if (Number.isNaN(parsed.getTime())) {
  console.log("Invalid date");
}
```

The corrected version works because ISO-style input is far more predictable across JavaScript engines.

## 7. Best Practices

### Practice 1: Store timestamps or ISO strings, not formatted text

Formatted strings are good for display, but they are a poor storage format because they depend on locale and are harder to compare.

```javascript
const stored = "2025-01-15T14:30:00.000Z";
const date = new Date(stored);
```

This approach keeps your data consistent and easy to reconstruct later.

### Practice 2: Use UTC when you need absolute time

If the time must mean the same thing everywhere, use UTC methods or ISO timestamps with `Z` at the end.

```javascript
const utcDate = new Date("2025-01-15T12:00:00Z");

console.log(utcDate.toISOString());
```

Output (tested with Node 24.21.0):

```text
2025-01-15T12:00:00.000Z
```

UTC avoids many time zone surprises when data is shared across systems.

### Practice 3: Validate dates before using them

A date object can exist but still be invalid. Check it before formatting or calculating with it.

```javascript
const candidate = new Date("not a date");

if (Number.isNaN(candidate.getTime())) {
  console.log("Please enter a valid date");
}
```

Output (tested with Node 24.21.0):

```text
Please enter a valid date
```

This prevents downstream bugs from invalid input.

## 8. Limitations and Edge Cases

- `Date` uses the system time zone by default, which can change how a moment is displayed.
- Daylight saving time can make local times repeat or skip, so adding 24 hours does not always mean the same local clock time tomorrow.
- Parsing non-ISO strings is implementation-dependent and can behave differently across environments.
- Months are zero-based in the constructor and getters, which is a common source of off-by-one bugs.
- `Date` has millisecond precision, so it is not suited for high-resolution timing.
- Very large or out-of-range values can produce an invalid date rather than a clean error.

> If you need calendar-only values, such as a birthday without a time of day, be careful: `Date` still represents a moment in time, so time zone conversion can shift the displayed day.

## 9. Practical Mini Project

This mini project builds a small function that prints a countdown message for an event. It combines creation, comparison, and formatting in one place.

```javascript
function daysUntilEvent(eventDate) {
  const now = new Date();
  const target = new Date(eventDate);

  if (Number.isNaN(target.getTime())) {
    return "Invalid event date";
  }

  const msPerDay = 24 * 60 * 60 * 1000;
  const diff = target.getTime() - now.getTime();
  const days = Math.ceil(diff / msPerDay);

  if (days < 0) {
    return "The event has already passed";
  }

  return `${days} day(s) left`;
}

console.log(daysUntilEvent("2025-12-31T00:00:00Z"));
```

This example shows a practical workflow: validate the input, compare timestamps, and return a readable result.

## 10. Key Points

- `Date` represents a specific moment in time, not just a calendar day.
- The internal value is milliseconds since the Unix epoch.
- Month numbers are zero-based in constructors and getters.
- Use timestamps for comparisons and calculations.
- Use locale-aware formatting for user-facing display.
- Prefer ISO 8601 or numeric construction for reliable parsing.

## 11. Practice Exercise

- Create a function named `formatMeetingDate` that takes a date string.
- Return `"Invalid date"` if the input cannot be parsed.
- Otherwise, return a string in the form `"Wednesday, March 12, 2025"`.
- Use built-in `Date` methods only.

**Expected output:** A readable, validated long-form date string.

**Hint:** Check the result with `Number.isNaN(date.getTime())`, then use `toLocaleDateString()` with options.

```javascript
function formatMeetingDate(dateString) {
  const date = new Date(dateString);

  if (Number.isNaN(date.getTime())) {
    return "Invalid date";
  }

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

console.log(formatMeetingDate("2025-03-12T09:00:00Z"));
console.log(formatMeetingDate("hello"));
```

Output (tested with Node 24.21.0):

```text
Wednesday, March 12, 2025
Invalid date
```

## 12. Final Summary

`Date` is the standard JavaScript object for working with moments in time, timestamps, and readable date output. It is simple to create, but its behavior around months, parsing, and time zones requires attention.

For most everyday work, the safest approach is to store dates as ISO strings or timestamps, compare values with `getTime()`, and format output only when you display it to a user. That keeps your code predictable and reduces time zone surprises.

If you want to go further, the next topic to learn is JavaScript time zones and locale formatting, because those are the pieces that most often determine whether a date feature feels correct to users.
