last update

Johan Sebergsen Steinberg

How to use Javascript Date with host environment’s local timezone

The most intuitive basics of landing Javascript (JS) Date and local timezone, with or without DTS.

Tags:

The Apollo 11 lunar landing module Eagle, with astronauts Neil Armstrong and Buzz Aldrin aboard, is photographed above the moon by crewmate Michael Collins on the Columbia command module during rendezvous operations on July 21, 1969.

July 20, 1969, 20:17:40 UTC, Neil Armstrong and Buzz Aldrin are the first to land on Earth’s moon (photo by crewmate Michael Collins, read more at Space.com)

Besides using new Date(), which creates a Date object for the current time with device local timezone, there’s two consistent ways (excluding timestamp that I haven’t worked with) to use a Date object intuitively with local timezone and DTS. Technically, but should rarely matter, the local timezone is not stored in the Date object, but is determined by the host environment.


First option: Setting new Date by individual date and time parameters

A date can be set by passing individual number parameters. Besides year and month index, they’re all optional.

// new Date(year, monthIndex, day, hours, minutes, seconds, milliseconds);
const landingDate = new Date(1969, 5, 20);

Go to result

Two things to note:

  1. Month is index based, i.e., January is 0.
  2. About time, if time is omitted, the time will be midnight device local timezone.

Avoid setting new Date by date-time-string-format parameter because of it’s inconsistency between included time and excluded

new Date("1969-06-20") – i.e. datestring as parameter – might seem to give the same result as number parameters, but when you only pass a date it will set it to midnight UTC time, then the host environment adds the local timezone offset.

const landingDateTimeOff = new Date("1969-06-20");

Go to result

One exception may be if you want to set the time in a different timezone (but prefer the “preferred” option below)

const landingTime = new Date("1969-06-20T20:17:40.000Z")

Go to result

new Date("1969-06-20T20:17:40.000Z") works as expected, and could be considered the exception to the rule in the case of the moon landing to avoid setting the time with local timezone, but prefer using the “preferred” option below if you can.


Preferred option: Mutate Date by set methods

A date can also be set, statement by statement, by Date’s set methods that mutates a Date-object. They also has setUTC variants.

const satLandingDate = new Date();

satLandingDate.setFullYear(1969);
satLandingDate.setMonth(5);
satLandingDate.setDate(20);

const satLandingTime = new Date(satLandingDate);

satLandingTime.setUTCHours(20);
satLandingTime.setUTCMinutes(17);
satLandingTime.setUTCSeconds(40);

Go to result

Two things to note:

  1. Again, month is index based.
  2. But about time, when not set, it will of course be the original Date-object’s time.

Despite the mess of mutating a variable, this approach can be used to flexibly work with dates and, as utility, used variables can be avoided mutated, e.g.:

const addYears = (years: number, d = new Date()): Date => {
	const d2 = new Date(d);
	d2.setFullYear(d.getFullYear() + years);
	return d2;
};

const hundredYearAnniversary = addYears(100, landingDate);

Go to result


Other pitfalls

Avoid toISOString() unless you specifically don’t want local date and time representation, as it converts the Date to UTC.

Rather use a Date’s get methods in a utility function:

const isoDate = (d = new Date()) => [
	d.getFullYear(),
	String(d.getMonth() + 1).padStart(2, "0"),
	String(d.getDate()).padStart(2, "0"),
].join("-");

const landingDay = isoDate(satLandingDate);

landingDay

1969-06-20

For further reading, Maggie’s Blog further explains these problems in Fixing JavaScript Date – Web Compatibility and Reality.