The guides area is designed to help developers learn to better interact with the date and time problem domain, and the Moment Timezone library. These guides are specifically limited to concepts around time zones and how they're handled by Moment Timezone.
For more general date and time advice, see the core Moment.js guides.
Frequently, people are confused about the difference between time zones and UTC offsets.
The core Moment.js documentation has a guide on this topic that is worth reading first. Logically it belongs in the guides for Moment Timezone, but it predates this guide section by many years, and moving it would break a lot of links on the internet.
For an in depth description of zones vs offsets, see the Stack Overflow tag.
Moment Timezone enhances the core Moment.js functionality by using pre-compiled time zone data.
This section describes where the data comes from, its limitations, and some quirks of real-world time zone rules. The technical details of the data format are described in the API documentation.
All time zone data in Moment Timezone comes from the IANA Time Zone Database ("tzdb"). Moment Timezone consumes the default data directly from the tzdb, using only the published releases. The only changes the library makes are to convert the data to a custom JSON format, and optionally restrict how many years of data to use.
Any pull requests that make changes to the compiled data files without being derived from a tzdb release will be rejected.
If you think that the data used by Moment Timezone is incorrect, the ideal order of actions to follow is:
By default, Moment Timezone includes all the data from the IANA Time Zone Database ("tzdb"). This covers past data as far back as the 1800s for some zones, and future data up to the year 2499. This is usually more data than required by most applications, so there are also some pre-built data bundles available with more limited year ranges. These are listed on the project homepage and the "Where to use it" documentation (or you can use utility functions to create custom date ranges).
A question that often pops up with these limited bundles is: What happens for dates outside the range of the data? For example, if the loaded data only covers 2012 to 2022, and a date is calculated for 2023, or 2010, what is the calculated UTC offset for that date?
Due to the structure of the data format, the time zone rules at the boundaries of the data range are assumed to extended infinitely into the past and future. This produces the following behaviour:
As an example, let's say a project is using a data file that covers only 2015 to 2025, and wants to calculate the time in Sydney, Australia some time in 2026.
Australia/Sydney
has a base (standard) offset of UTC+10:00
from April to September each year.
Daylight Saving Time (DST) in Sydney applies from October to March, putting the offset at UTC+11:00
.UTC+11:00
. This is correct, but only by accident.
Calculating a date after March in 2026 will still get an offset of UTC+11:00
, even though the real value should be UTC+10:00
.
This is when bugs will start to appear.The best fix for these calculation problems is to make sure you're using a data range that covers all the dates your project needs.
Time zones that use daylight saving time (DST) vary about when they implement the time jumps. You shouldn't assume that the rules you're familiar with from a local time zone translate to other zones.
One difference that often catches out developers is that some zones change clocks at midnight.
A good example comes from Jordan (Asia/Amman
) in 2021:
2021-03-25 23:59:59
was 2021-03-26 01:00:00
(DST started).2021-10-29 00:59:59
was 2021-10-29 00:00:00
(DST stopped).This creates the situation where midnight at the start of March 26 didn't happen, while midnight on October 29 happened twice.
Moment Timezone accounts for these oddities as described in the "Parsing Ambiguities" documentation. But applications can still have bugs when they make other assumptions about time jumps, especially regarding the start of a day. So be aware that a day doesn't always start at midnight.