Background
JavaScript's Date
object tracks time in UTC internally, but typically accepts input and output in the local time of the computer it's running on. It doesn't have any facilities for working with time in other time zones. It can parse and output dates that are UTC or Local, but it can't directly work with other time zones.
To be absolutely precise, the internal representation of a Date
object is a single number, representing the number of milliseconds that have elapsed since 1970-01-01 00:00:00 UTC
, without regard to leap seconds. There is no time zone or string format stored in the Date object itself. When various functions of the Date
object are used, the computer's local time zone is applied to the internal representation. If the function produces a string, then the computer's locale information may be taken into consideration to determine how to produce that string. The details vary per function, and some are implementation-specific.
Libraries
Fortunately, there are libraries that can be used to work with time zones. Though they still cannot make the Date
object behave any differently, they typically implement the standard Olson/IANA timezone database and provide functions for using it in JavaScript. Some have overhead if you are running in a web browser, as the database can get a bit large if you want the whole thing. Fortunately, many of these libraries allow you to selectively choose which zones you want to support, making the data size much more palatable. Also some use modern features to get time zone data from the Intl
API instead of having to ship it themselves.
There are several libraries for this that I am aware of:
Luxon is probably the safest bet for all modern usage, and is the lightest weight as it uses the Intl
API for its timezone data.
Moment-timezone is an extension to moment.js, and brings its own time zone data.
js-joda is a JavaScript implementation of the Joda-Time API (from Java), and includes time zone support through a separate module.
date-fns-tz is an extension for date-fns 2.x. date-fns-timezone is an extension for date-fns 1.x.
BigEasy/TimeZone also appears to be on the right track.
WallTime-js has reached end-of-life, and the owners are migrating to moment-timezone.
TimeZoneJS has been around the longest, but is known to have some long-standing bugs, especially near daylight saving time transitions. Hopefully these will be fixed at some point in the future.
tz.js has also been around for some time, but isn't very well documented, IMHO.
You should evaluate these libraries to see which will meet your needs. If unsure, go with moment/moment-timezone.
Native Support in Modern Environments
If you can limit your usage to modern environments, you can now do the following without any special libraries:
new Date().toLocaleString("en-US", {timeZone: "America/New_York"})
This isn't a comprehensive solution, but it works for many scenarios that require only output conversion (from UTC or local time to a specific time zone, but not the other direction). This is part of the ECMAScript Internationalization API (ECMA-402). See this post for more details. This compatibility table tracks which versions are supported. This is the Intl
API mentioned above that certain libraries are using internally now.
(To be clear, this doesn't initialize a Date
object, but can be used to apply a time zone when producing a locale-specific string representation.)
Future Proposals
The TC39 Temporal Proposal aims to provide a new set of standard objects for working with dates and times in the JavaScript language itself. This will include support for a time zone aware object.
0
Created by Matt Johnson-Pint on 2020-03-07 15:54:22 +0000 UTC
Share