JavaScript Date UTC and Timezone Conversions

The JavaScript Date object manages time by storing a single numeric value representing milliseconds elapsed since the Unix Epoch in Universal Coordinated Time (UTC). While the internal representation is always timezone-agnostic UTC, the Date object automatically uses the runtime environment’s local timezone settings when parsing input strings and formatting output for display. This guide explains how JavaScript handles the distinction between UTC and local time, how parsing affects timezone context, and how to convert between the two reliably.

Internal Storage: The Unix Epoch

Every JavaScript Date instance wraps a single integer: the number of milliseconds since January 1, 1970, 00:00:00 UTC. The object does not store a timezone identifier (like “America/New_York” or “UTC”). Instead, the timezone is applied dynamically whenever you read from or write to the Date instance.

const now = new Date();
console.log(now.getTime()); // Outputs raw milliseconds since Unix Epoch (UTC)

Parsing Inputs and Timezone Interpretation

How JavaScript interprets a date string depends heavily on its format:

// Parsed as UTC midnight
const utcDate = new Date("2023-10-15");

// Parsed as local midnight
const localDate = new Date("2023-10-15T00:00:00");

// Parsed as UTC midnight
const explicitUtc = new Date("2023-10-15T00:00:00Z");

Accessing Values: Local vs. UTC Methods

The Date prototype provides two complementary sets of getter and setter methods.

Local Time Methods

Local methods retrieve or set components according to the host system’s current timezone and Daylight Saving Time (DST) rules:

const date = new Date("2023-10-15T12:00:00Z");

// Outputs values based on your computer's local timezone
console.log(date.getHours());
console.log(date.toString());

UTC Methods

UTC methods bypass the local timezone and interact directly with the UTC values:

const date = new Date("2023-10-15T12:00:00Z");

// Always outputs 12, regardless of local timezone
console.log(date.getUTCHours()); 
console.log(date.toISOString()); // "2023-10-15T12:00:00.000Z"

Determining the Local Timezone Offset

To determine the difference between the local timezone and UTC, use the getTimezoneOffset() method.

const offset = new Date().getTimezoneOffset();
// In New York (EDT, UTC-4), offset is 240
// In Tokyo (JST, UTC+9), offset is -540

Converting to Target Timezones Using Intl

The standard Date object cannot switch its internal context to an arbitrary third timezone (e.g., displaying Tokyo time while running in New York). To perform arbitrary timezone conversions, use the Intl.DateTimeFormat API:

const date = new Date("2023-10-15T12:00:00Z");

const tokyoTime = new Intl.DateTimeFormat("en-US", {
  timeZone: "Asia/Tokyo",
  dateStyle: "full",
  timeStyle: "long",
}).format(date);

console.log(tokyoTime);