Date.UTC()

Build a timestamp from calendar components interpreted as UTC rather than local time.

Signature
Date.UTC(year)
Date.UTC(year, monthIndex)
Date.UTC(year, monthIndex, day)
Date.UTC(year, monthIndex, day, hours)
Date.UTC(year, monthIndex, day, hours, minutes)
Date.UTC(year, monthIndex, day, hours, minutes, seconds)
Date.UTC(year, monthIndex, day, hours, minutes, seconds, milliseconds)
  • Added in JavaScript ES1

Parameters

ParameterTypeDescription
$yearnumberThe year. Integers 0 to 99 are converted to 1900 + year, so 95 means 1995; all other values are the literal year.
$monthIndexoptionalnumber= 0The month as a zero-based index, 0 for January through 11 for December.
$dayoptionalnumber= 1The day of the month.
$hoursoptionalnumber= 0The hour of the day, 0 to 23.
$minutesoptionalnumber= 0The minutes past the hour.
$secondsoptionalnumber= 0The seconds past the minute.
$millisecondsoptionalnumber= 0The milliseconds past the second.

Return value

numberA number: the timestamp in milliseconds since 1 January 1970 UTC for the supplied components, read as UTC. Returns NaN if any argument coerces to NaN or the result is out of range.

Errors

Never throws — invalid or out-of-range components yield NaN.

Changelog

  • PHP ES2017Calling Date.UTC() with a single argument is required to treat the omitted monthIndex as 0. Older engines returned NaN, so Date.UTC(2017) was unusable before this change.

Date.UTC() is the counterpart to the multi-argument Date constructor. Both take the same calendar components, but the constructor reads them in the running machine's local timezone while Date.UTC() reads them as UTC. It returns a raw timestamp, so wrap it in new Date(...) when you need an object.

When to reach for it

Use it any time the result must not depend on where the code runs: test fixtures, date-range boundaries stored server-side, scheduled jobs, and anything you are about to compare against a timestamp that came from a database. new Date(2024, 0, 1) produces seven different instants across seven timezones; Date.UTC(2024, 0, 1) produces one.

What trips people up

monthIndex is zero-based here exactly as it is in the constructor — Date.UTC(2024, 1, 29) is 29 February, not 29 January. Only the month is offset; the day is a normal 1-based day of the month.

Components normalize rather than clamp, so out-of-range values carry into the neighbouring field: a monthIndex of 15 rolls the year forward and lands on April. And a two-digit year is quietly shifted into the 1900s, so Date.UTC(95, 0, 1) is 1995.

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • Create deterministic date fixtures that behave the same in CI and on a developer laptop
  • Define the start and end of a reporting window that must match a UTC database column
  • Convert year/month/day fields from a form into a single timestamp for storage
  • Compute the number of days between two calendar dates without DST distorting the result

Frequently asked questions

When should I use Date.UTC() instead of new Date(y, m, d)?

Whenever the resulting instant must be identical regardless of the machine's timezone — tests, stored range boundaries, scheduled jobs. The constructor reads the same components as local time, so its result shifts with the runner's clock settings.

Does Date.UTC() return a Date object?

No, it returns a number of milliseconds since the epoch. Wrap it as new Date(Date.UTC(...)) when you need an object to call methods on.

Why is Date.UTC(2024, 12, 25) in 2025?

Month index 12 is one past December, so it rolls forward into January 2025. December is index 11 — subtract one from the human month number.

More examples

Why fixtures should use it

The UTC value always prints 2024-01-01T00:00:00.000Z. The local one only matches in UTC itself — elsewhere the difference equals getTimezoneOffset(), which is why local fixtures fail in CI.

Example · javascript
const local = new Date(2024, 0, 1);          // local midnight
const utc   = new Date(Date.UTC(2024, 0, 1)); // UTC midnight

console.log(utc.toISOString());
console.log(local.getTime() === utc.getTime());

// The gap is exactly this machine's offset, in minutes
console.log((local.getTime() - utc.getTime()) / 60000);
console.log(local.getTimezoneOffset());

Counting days between calendar dates

Because UTC has no daylight saving, every day is exactly 86,400,000 ms and the division is exact. The same arithmetic on local dates returns 30.958 across a spring-forward boundary.

Example · javascript
const DAY = 86_400_000;

function daysBetween(a, b) {
  return (Date.UTC(...b) - Date.UTC(...a)) / DAY;
}

console.log(daysBetween([2024, 0, 1], [2024, 1, 1]));  // January
console.log(daysBetween([2024, 1, 1], [2024, 2, 1]));  // leap February
console.log(daysBetween([2023, 1, 1], [2023, 2, 1]));  // common February
console.log(daysBetween([2024, 0, 1], [2025, 0, 1]));  // whole leap year

The two-digit year rule

Years 0 to 99 map to 1900 + year, so 95 is 1995 and 0 is 1900. setUTCFullYear() has no such rule, which is the escape hatch for genuinely ancient dates.

Example · javascript
console.log(Date.UTC(95, 0, 1) === Date.UTC(1995, 0, 1));
console.log(new Date(Date.UTC(95, 0, 1)).getUTCFullYear());
console.log(new Date(Date.UTC(0, 0, 1)).getUTCFullYear());

// To mean an actual early year, set it explicitly
const early = new Date(Date.UTC(2024, 0, 1));
early.setUTCFullYear(95);
console.log(early.getUTCFullYear());

Discussion

  • Be the first to comment on this lesson.