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:
July 20, 1969, 20:17:40 UTC, Neil Armstrong and Buzz Aldrin are the first to land on the moon (photo by crewmate Michael Collins, read more at Space.com)
Armstrong and Aldrin landed on the moon in UTC time for their current host environment. For you to control time with old NASA proficiency using an API as old as the moon landing – Javascript Date
inspired by an ancient Java implementation – besides parameter-free new Date()
for current device local time, there’s two consistent ways to use a Date object intuitively with local timezone and DTS.
A technicality to note is that the local timezone is not stored in the Date object, but is determined by the host environment
.
First option: Defining new Date by individual date and time parameters
A date can be defined by passing individual number parameters. Besides year and month index, they’re all optional.
// Syntax:
// new Date(year, monthIndex, day, hours, minutes, seconds, milliseconds)
const landingDate = new Date(1969, 5, 20)
// Fri Jun 20 1969 00:00:00 GMT[+-HHmm] ([local timezone label])
Two things to note:
- month is index based, i.e., january is 0
- if time is omitted, time will be midnight device local timezone
Avoid date-time-string-format!
Avoid new Date()
parameter in date-time-string-format 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 landingDateMidnightOffset = new Date("1969-06-20");
// [Day Month date …] 1969 [… and time including timezone offset from midnight] GMT[+-HHmm] ([local timezone label])
… but there might be an exception
When you want to set the time in UTC, date-time-string-format works as intended. But the option further below might be preferred for consistency.
const landingTime = new Date("1969-06-20T20:17:40.000Z")
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 have setUTC
variants.
Note two things:
- month is index based again
- time, when not set, is local current time or the original Date-object’s time
const satLandingDate = new Date();
// Mutate Date object
satLandingDate.setFullYear(1969);
satLandingDate.setMonth(5);
satLandingDate.setDate(20);
const satLandingTime = new Date(satLandingDate);
// Mutate Date object
satLandingTime.setUTCHours(20);
satLandingTime.setUTCMinutes(17);
satLandingTime.setUTCSeconds(40);
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 newDate = new Date(d);
newDate.setFullYear(d.getFullYear() + years);
return newDate;
};
const hundredYearAnniversary = addYears(100, landingDate);
Other pitfalls
Avoid toISOString()
unless you specifically don’t want local date and time representation, as it converts the Date to UTC.
To get a plain date string, rather use a Date’s get methods in a utility function:
const getPlainDateString = (d = new Date()) => [
d.getFullYear(),
String(d.getMonth() + 1).padStart(2, "0"),
String(d.getDate()).padStart(2, "0"),
].join("-");
const landingDay = getPlainDateString(satLandingDate);
For further reading, Maggie’s Blog further explains these problems in Fixing JavaScript Date – Web Compatibility and Reality.