# Technical Documentation: moment/moment-timezone

> ℹ️ **Provenance:** Hybrid Fusion: `moment/moment-timezone` + DevDocs `moment_timezone` · [CodeWiki Reference](https://codewiki.google/github.com/moment/moment-timezone) · Recency: Active (< 180 days)

## 1. Repository Overview (moment/moment-timezone)

# [Moment Timezone](http://momentjs.com/timezone/)

[![NPM version][npm-version-image]][npm-url]
[![NPM downloads][npm-downloads-image]][npm-download-url]
[![MIT License][license-image]][license-url]
[![Build Status][ci-image]][ci-url]
[![FOSSA Status][fossa-badge-image]][fossa-badge-url]

IANA Time zone support for Moment.js

## Project Status

Moment-Timezone is an add-on for Moment.js.  Both are considered legacy projects, now in maintenance mode.  In most cases, you should choose a different library.

For more details and recommendations, please see [Project Status](https://momentjs.com/docs/#/-project-status/) in the Moment docs.

*Thank you.*

## Resources

- [Documentation](https://momentjs.com/timezone/docs/)
- [Changelog](changelog.md)
- [Stack Overflow](https://stackoverflow.com/questions/tagged/moment-timezone)

## Examples

```js
var june = moment("2014-06-01T12:00:00Z");
june.tz('America/Los_Angeles').format('ha z'); // 5am PDT
june.tz('America/New_York').format('ha z');    // 8am EDT
june.tz('Asia/Tokyo').format('ha z');          // 9pm JST
june.tz('Australia/Sydney').format('ha z');    // 10pm EST

var dec = moment("2014-12-01T12:00:00Z");
dec.tz('America/Los_Angeles').format('ha z');  // 4am PST
dec.tz('America/New_York').format('ha z');     // 7am EST
dec.tz('Asia/Tokyo').format('ha z');           // 9pm JST
dec.tz('Australia/Sydney').format('ha z');     // 11pm EST
```

## License

Moment-timezone is freely distributable under the terms of the [MIT license][license-url].

[![FOSSA Status][fossa-large-image]][fossa-large-url]


[license-image]: https://img.shields.io/badge/license-MIT-blue.svg?style=flat
[license-url]: LICENSE

[npm-url]: https://npmjs.org/package/moment-timezone
[npm-version-image]: https://img.shields.io/npm/v/moment-timezone.svg?style=flat

[npm-downloads-image]: https://img.shields.io/npm/dm/moment-timezone.svg?style=flat
[npm-download-url]: https://npmcharts.com/compare/moment-timezone?minimal=true

[ci-url]: https://github.com/moment/moment-timezone/actions/workflows/tests.yml?query=branch%253Adevelop
[ci-image]: https://github.com/moment/moment-timezone/actions/workflows/tests.yml/badge.svg?query=branch%253Adevelop

[fossa-badge-image]: https://app.fossa.io/api/projects/git%2Bhttps%3A%2F%2Fgithub.com%2Fmoment%2Fmoment-timezone.svg?type=shield
[fossa-badge-url]: https://app.fossa.io/projects/git%2Bhttps%3A%2F%2Fgithub.com%2Fmoment%2Fmoment-timezone?ref=badge_shield

[fossa-large-image]: https://app.fossa.io/api/projects/git%2Bhttps%3A%2F%2Fgithub.com%2Fmoment%2Fmoment-timezone.svg?type=large
[fossa-large-url]: https://app.fossa.io/projects/git%2Bhttps%3A%2F%2Fgithub.com%2Fmoment%2Fmoment-timezone?ref=badge_large

## 2. Official Technical Reference (DevDocs: Moment.js Timezone)

# DevDocs Technical Reference: moment_timezone

> Source: DevDocs.io (moment_timezone) | Formatted for AI Agents & Developers | Zero-Egress Edge Persistence


## Section: index

# Moment.js Timezone

   

## Where to use it

     

To use moment-timezone, you will need `moment@2.9.0+`, `moment-timezone.js`, and the `moment-timezone` data.

 

For convenience, there are builds available on [momentjs.com/timezone/](https://momentjs.com/timezone/) with all the zone data or a subset of the data.

 
 - 
`moment-timezone-with-data.js` is recommended for server environments (Node.js) and covers all years available.
 - 
`moment-timezone-with-data-10-year-range.js` is recommend for most browser environments, covering +/- 5 years from the year published.
 - 
`moment-timezone-with-data-1970-2030.js` covers a 60 year range, for those that need more data but not the larger file size of the full data file.
 
 

If you use one of the above files, you still need `moment.js`, but you do not need `moment-timezone.js` because it is included.

     

###  Node.js 

    

```
npm install moment-timezone
```

  

In Node.js, all the data is preloaded. No additional code is needed for loading data.

 

```
var moment = require('moment-timezone');
moment().tz("America/Los_Angeles").format();
```

 

In ECMAScript native module format (or in TypeScript):

  

```
import moment from 'moment-timezone';
moment().tz("America/Los_Angeles").format();
```

 

**Note:** You don't need to require/import the base `moment` library as well. Moment Timezone will automatically load and extend the `moment` module, then return the modified instance.

 

Package managers like `npm` and `yarn` can sometimes create situations where multiple versions of `moment` are installed. Importing *only* from `moment-timezone` can help ensure that the same version is used consistently. See [this comment on issue #982](https://github.com/moment/moment-timezone/issues/982#issuecomment-1119540905) for a much more detailed explanation, including steps to fix potential versioning problems.

  

```
// Unnecessary, can cause issues with package managers
import moment from 'moment';
import 'moment-timezone';

// Correct
import moment from 'moment-timezone';
```

 

The [pre-built bundles](https://momentjs.com/timezone/) are also included in the `npm` package, and can be loaded directly. These allow you to import the library with a smaller subset of data.

  

```
import moment from 'moment-timezone/builds/moment-timezone-with-data-10-year-range.js'; // or .min.js
```

 

You can also import just the library without any preloaded data.

  

```
import moment from 'moment-timezone/moment-timezone.js'; // or .min.js
moment.tz.load(customData);
```

     

###  Browser 

    

```

```

  

When using Moment Timezone in the browser, you will need to load the data as well as the library.

 

You can either use the prebuilt library and data files linked on [the homepage](https://momentjs.com/timezone/) or build a subset of the data yourself and [load it](#/data-loading/).

 

```
moment().tz("America/Los_Angeles").format();
```

     

###  Require.js 

    

```
require.config({
    paths: {
        "moment": "path/to/moment"
    }
});
define(["path/to/moment-timezone-with-data"], function (moment) {
    moment().tz("America/Los_Angeles").format();
});
```

      

###  Webpack 

    

```
npm install moment-timezone
```

  

```
var moment = require('moment-timezone');
moment().tz("America/Los_Angeles").format();
```

 

**Note:** By default, webpack bundles *all* moment-timezone data (in moment-timezone 0.5.25, that’s over 900 KBs minified). To strip out unwanted data and bundle only the zone and date range data you need, add the [`moment-timezone-data-webpack-plugin`](https://www.npmjs.com/package/moment-timezone-data-webpack-plugin) package:

  

```
// webpack.config.js
const MomentTimezoneDataPlugin = require('moment-timezone-data-webpack-plugin');
const currentYear = new Date().getFullYear();

module.exports = {
    plugins: [
        // To include only specific zones, use the matchZones option
        new MomentTimezoneDataPlugin({
            matchZones: /^America/
        }),

        // To keep all zones but limit data to specific years, use the year range options
        new MomentTimezoneDataPlugin({
            startYear: currentYear - 5,
            endYear: currentYear + 5,
        }),
    ],
};
```

 

Alternatively, the [pre-built bundles](https://momentjs.com/timezone/) are also included in the `npm` package, and can be loaded directly. See the [Node.js section](#/use-it/node-js) for more details.

 

Also see the primary [Moment.js Webpack documentation](https://momentjs.com/docs/#/use-it/webpack/) for an example of how to reduce Moment’s bundled locale data. Together these techniques can significantly reduce the final bundle size (by over 1 MB minified, or 85 KB minified + gzipped).

     

## Using Time zones

     

There are two interfaces for using time zones with Moment.js.

 

`moment.tz(..., String)` does *parsing in given time zone*

 

It takes all the same arguments as the `moment` constructor, but uses the last argument as a time zone identifier:

 

```
var a = moment.tz("2013-11-18 11:55", "Asia/Taipei");
var b = moment.tz("2013-11-18 11:55", "America/Toronto");

a.format(); // 2013-11-18T11:55:00+08:00
b.format(); // 2013-11-18T11:55:00-05:00

a.utc().format(); // 2013-11-18T03:55Z
b.utc().format(); // 2013-11-18T16:55Z
```

 

Note that created moments have different UTC time because these moments were created in different time zones.

 

`moment().tz(String)` does *converting to provided time zone*

 

```
var a = moment.utc("2013-11-18 11:55").tz("Asia/Taipei");
var b = moment.utc("2013-11-18 11:55").tz("America/Toronto");

a.format(); // 2013-11-18T19:55:00+08:00
b.format(); // 2013-11-18T06:55:00-05:00

a.utc().format(); // 2013-11-18T11:55Z
b.utc().format(); // 2013-11-18T11:55Z
```

 

In this example, you first create `moment.utc("2013-11-18 11:55")` object in UTC, and then change its timezone to specified. This also works if you create the object in your default timezone: `moment("2013-11-18 11:55")`.

 

Note that created moments have equal UTC time because these moments were created in a [default timezone](#/using-timezones/default-timezone/).

     

###  Parsing in Zone 

    

```
moment.tz(..., String);
```

  

The `moment.tz` constructor takes all the same arguments as the `moment` constructor, but uses the last argument as a [time zone identifier](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones).

 

```
var a = moment.tz("2013-11-18 11:55", "America/Toronto");
var b = moment.tz("May 12th 2014 8PM", "MMM Do YYYY hA", "America/Toronto");
var c = moment.tz(1403454068850, "America/Toronto");
a.format(); // 2013-11-18T11:55:00-05:00
b.format(); // 2014-05-12T20:00:00-04:00
c.format(); // 2014-06-22T12:21:08-04:00
```

 

This constructor is DST aware, and will use the correct offset when parsing.

 

```
moment.tz("2013-12-01", "America/Los_Angeles").format(); // 2013-12-01T00:00:00-08:00
moment.tz("2013-06-01", "America/Los_Angeles").format(); // 2013-06-01T00:00:00-07:00
```

 

The offset is only taken into consideration when constructing with an array, string without offset, or object.

 

```
var arr = [2013, 5, 1],
    str = "2013-12-01",
    obj = { year : 2013, month : 5, day : 1 };

moment.tz(arr, "America/Los_Angeles").format(); // 2013-06-01T00:00:00-07:00
moment.tz(str, "America/Los_Angeles").format(); // 2013-12-01T00:00:00-08:00
moment.tz(obj, "America/Los_Angeles").format(); // 2013-06-01T00:00:00-07:00

moment.tz(arr, "America/New_York").format();    // 2013-06-01T00:00:00-04:00
moment.tz(str, "America/New_York").format();    // 2013-12-01T00:00:00-05:00
moment.tz(obj, "America/New_York").format();    // 2013-06-01T00:00:00-04:00
```

 

If the input string contains an offset, it is used instead for parsing. The parsed moment is then converted to the target zone.

 

```
var zone = "America/Los_Angeles";
moment.tz('2013-06-01T00:00:00',       zone).format(); // 2013-06-01T00:00:00-07:00
moment.tz('2013-06-01T00:00:00-04:00', zone).format(); // 2013-05-31T21:00:00-07:00
moment.tz('2013-06-01T00:00:00+00:00', zone).format(); // 2013-05-31T17:00:00-07:00
```

 

Unix timestamps and `Date` objects refer to specific points in time, thus it doesn't make sense to use the time zone offset when constructing. Using `moment.tz(Number|Date, zone)` is functionally equivalent to `moment(Number|Date).tz(zone)`.

 

```
var timestamp = 1403454068850,
    date = new Date(timestamp);

moment.tz(timestamp, "America/Los_Angeles").format(); // 2014-06-22T09:21:08-07:00
moment(timestamp).tz("America/Los_Angeles").format(); // 2014-06-22T09:21:08-07:00

moment.tz(date, "America/Los_Angeles").format();      // 2014-06-22T09:21:08-07:00
moment(date).tz("America/Los_Angeles").format();      // 2014-06-22T09:21:08-07:00
```

 

Уou may specify a boolean right after format argument to use strict parsing. Strict parsing requires that the format and input match exactly, *including delimeters*.

 

```
moment.tz('It is 2012-05-25', 'YYYY-MM-DD', "America/Toronto").isValid();       // true 
moment.tz('It is 2012-05-25', 'YYYY-MM-DD', true, "America/Toronto").isValid(); // false
moment.tz('2012-05-25', 'YYYY-MM-DD', true, "America/Toronto").isValid();       // true
moment.tz('2012-05.25', 'YYYY-MM-DD', true, "America/Toronto").isValid();       // false
```

     

###  Parsing Ambiguities 

   

Due to daylight saving time, there is a possibility that a time either does not exist, or has existed twice.

 

### Spring Forward

 

In the spring, at the start of DST, clocks move forward an hour. In reality though, it is not time that is moving, it is the offset moving.

 

Moving the offset forward gives the illusion that an hour has disappeared. As the clock ticks, you can see it move from `1:58` to `1:59` to `3:00`. It is easier to see what is actually happening when you include the offset.

 

```
1:58 -5
1:59 -5
3:00 -4
3:01 -4
```

 

The result is that any time between `1:59:59` and `3:00:00` never actually happened. Moment Timezone accounts for this. If you try to parse a time that never existed, it will skip forward by the amount of the DST gap (usually 1 hour).

 

```
moment.tz("2012-03-11 01:59:59", "America/New_York").format() // 2012-03-11T01:59:59-05:00
moment.tz("2012-03-11 02:00:00", "America/New_York").format() // 2012-03-11T03:00:00-04:00
moment.tz("2012-03-11 02:59:59", "America/New_York").format() // 2012-03-11T03:59:59-04:00
moment.tz("2012-03-11 03:00:00", "America/New_York").format() // 2012-03-11T03:00:00-04:00
```

 

In this example, the two o'clock hour doesn't exist, so it is treated as equivalent to the three o'clock hour.

 

### Fall Back

 

In the fall, at the end of DST, clocks move backward an hour. Again, time is not moving backwards, only the offset is. In this case, the illusion is that an hour repeats itself.

 

Again, it is easier to see what is actually happening when you include the offset.

 

```
1:58 -4
1:59 -4
1:00 -5
1:01 -5
```

 

Moment Timezone handles this by always using the earlier instance of a duplicated hour.

 

```
moment.tz("2012-11-04 00:59:59", "America/New_York"); // 2012-11-04T00:59:59-04:00
moment.tz("2012-11-04 01:00:00", "America/New_York"); // 2012-11-04T01:00:00-04:00
moment.tz("2012-11-04 01:59:59", "America/New_York"); // 2012-11-04T01:59:59-04:00
moment.tz("2012-11-04 02:00:00", "America/New_York"); // 2012-11-04T02:00:00-05:00
```

 

You won't be able to create a moment with the later instance of the duplicated hour unless you include the offset when parsing.

 

```
moment.tz("2012-11-04 01:00:00-04:00", "America/New_York"); // 2012-11-04T01:00:00-04:00
moment.tz("2012-11-04 01:00:00-05:00", "America/New_York"); // 2012-11-04T01:00:00-05:00
```

     

###  Converting to Zone 

    

```
moment().tz(String);
moment().tz(String, Boolean);
```

  

The `moment#tz` mutator will change the time zone and update the offset.

 

```
moment("2013-11-18").tz("America/Toronto").format('Z'); // -05:00
moment("2013-11-18").tz("Europe/Berlin").format('Z');   // +01:00
```

 

This information is used consistently in other operations, like calculating the start of the day.

 

```
var m = moment.tz("2013-11-18 11:55", "America/Toronto");
m.format();                     // 2013-11-18T11:55:00-05:00
m.startOf("day").format();      // 2013-11-18T00:00:00-05:00
m.tz("Europe/Berlin").format(); // 2013-11-18T06:00:00+01:00
m.startOf("day").format();      // 2013-11-18T00:00:00+01:00
```

 

Without any argument, `moment#tz` returns:

 
 - the time zone name assigned to the moment instance or
 - 
`undefined` if a time zone has not been set.
 
 

```
var m = moment.tz("2013-11-18 11:55", "America/Toronto");
m.tz();  // America/Toronto
var m = moment.tz("2013-11-18 11:55");
m.tz() === undefined;  // true
```

 

On passing a second parameter as `true`, only the timezone (and offset) is updated, keeping the local time same. Consequently, it will now point to a different point in time if the offset has changed.

 

```
var m = moment.tz("2013-11-18 11:55", "America/Toronto");
m.format();                           // 2013-11-18T11:55:00-05:00
m.tz('Europe/Berlin', true).format()  // 2013-11-18T11:55:00+01:00
```

     

###  Formatting Additions 

    

```
moment.tz(String).format("Z z"); // -08:00 PST
moment.tz(String).zoneAbbr();    // PST
moment.tz(String).zoneName();    // PST
```

  

In addition to including the `+00:00` formatting information, Moment Timezone also includes information for the abbreviated time zone name.

 

```
moment.tz([2012, 0], 'America/New_York').format('z');    // EST
moment.tz([2012, 5], 'America/New_York').format('z');    // EDT
moment.tz([2012, 0], 'America/Los_Angeles').format('z'); // PST
moment.tz([2012, 5], 'America/Los_Angeles').format('z'); // PDT
```

 

Note that these abbreviations may change depending on the time zone offset. This helps to distinguish offsets between places that may or may not use DST.

 

```
// Denver observes DST
moment.tz([2012, 0], 'America/Denver').format('Z z');  // -07:00 MST
moment.tz([2012, 5], 'America/Denver').format('Z z');  // -06:00 MDT
// Phoenix does not observe DST
moment.tz([2012, 0], 'America/Phoenix').format('Z z'); // -07:00 MST
moment.tz([2012, 5], 'America/Phoenix').format('Z z'); // -07:00 MST
```

 

Note also that these abbreviations are not globally unique. Below, you can see that both United States Central Standard Time and China Standard Time have the same abbreviation.

 

```
moment.tz('2016-01-01', 'America/Chicago').format('z');    // CST
moment.tz('2016-01-01', 'Asia/Shanghai').format('z');      // CST
```

 

You can also use `moment#zoneAbbr` to get the zone abbreviation. This is what moment.js uses when formatting the `z` token.

 

```
moment.tz([2012, 0], 'America/New_York').zoneAbbr(); // EST
moment.tz([2012, 5], 'America/New_York').zoneAbbr(); // EDT
```

 

Moment.js also provides a hook for the long form time zone name. Because these strings are generally localized, Moment Timezone does not provide any long names for zones.

 

To provide long form names, you can override `moment.fn.zoneName` and use the `zz` token.

 

```
var abbrs = {
    EST : 'Eastern Standard Time',
    EDT : 'Eastern Daylight Time',
    CST : 'Central Standard Time',
    CDT : 'Central Daylight Time',
    MST : 'Mountain Standard Time',
    MDT : 'Mountain Daylight Time',
    PST : 'Pacific Standard Time',
    PDT : 'Pacific Daylight Time',
};

moment.fn.zoneName = function () {
    var abbr = this.zoneAbbr();
    return abbrs[abbr] || abbr;
};

moment.tz([2012, 0], 'America/New_York').format('zz');    // Eastern Standard Time
moment.tz([2012, 5], 'America/New_York').format('zz');    // Eastern Daylight Time
moment.tz([2012, 0], 'America/Los_Angeles').format('zz'); // Pacific Standard Time
moment.tz([2012, 5], 'America/Los_Angeles').format('zz'); // Pacific Daylight Time
```

 

Please note that the `z` formatting token will not always show the abbreviated time zone name, instead, will show the time offsets for each region.

 

```
moment.tz('America/Los_Angeles').format('z')  // "PDT"     (abbreviation)
moment.tz('Asia/Magadan').format('z')         // "+11"     (3-char offset)
moment.tz('Asia/Colombo').format('z')         // "+0530"   (5-char offset)
```

     

###  Default time zone 

    

```
moment.tz.setDefault(String);
```

  

By default, `moment` objects are created in the local time zone. The local time zone is determined by your JS environment such as a browser or server like Node.js.

 

To change the default time zone, use `moment.tz.setDefault` with a valid time zone.

 

```
moment.tz.setDefault("America/New_York");
```

 

To reset the default time zone to local, use `moment.tz.setDefault` with no arguments.

 

```
moment.tz.setDefault();
```

 

This is a global setting (shared by all modules).

 

Subsequent calls to `moment.tz.setDefault` will not affect existing `moment` objects or their clones.

     

###  Guessing user zone 

    

```
moment.tz.guess();
moment.tz.guess(Boolean);
```

  

Moment Timezone uses the Internationalization API (`Intl.DateTimeFormat().resolvedOptions().timeZone`) in [supported browsers](http://caniuse.com/#feat=internationalization) to determine the user's time zone.

 

On other browsers, time zone detection is rather tricky to get right, as there is little information provided by those browsers. For those, it will use `Date#getTimezoneOffset` and `Date#toString` on a handful of moments around the current year to gather as much information about the browser environment as possible. It then compares that information with all the time zone data loaded and returns the closest match. In case of ties, the time zone with the city with largest population is returned.

 

By default Moment Timezone caches the detected timezone. This means that subsequent calls to `moment.tz.guess()` will always return the same value.

 

You can call `moment.tz.guess()` with an optional boolean argument "ignoreCache". If set to true, the cache will be ignored and overwritten with the new value.

 

```
moment.tz.guess(); // America/Chicago
// suppose the client's timezone changes to Europe/Berlin
moment.tz.guess(); // America/Chicago
moment.tz.guess(true); // Europe/Berlin
moment.tz.guess(); // Europe/Berlin
```

     

###  Getting all Zones 

    

```
moment.tz.names(); // String[]
```

  

To get a list of all available time zone names, use `moment.tz.names`.

 

```
moment.tz.names(); // ["Africa/Abidjan", "Africa/Accra", "Africa/Addis_Ababa", ...]
```

     

###  Getting Zones for country 

    

```
moment.tz.zonesForCountry(String); // String[]
moment.tz.zonesForCountry(String, Boolean);
```

  

To get a list of time zones for some country, use `moment.tz.zonesForCountry()`. This takes an [ISO 3166-1](https://en.wikipedia.org/wiki/ISO_3166-1) two-letter country code.

 

```
moment.tz.zonesForCountry('US');
```

 

By default this method returns zone names sorted alphabetically:

 

```
["America/Adak", "America/Anchorage", ... "Pacific/Honolulu"]
```

 

To also get offsets, pass `true` as the 2nd parameter:

 

```
moment.tz.zonesForCountry('CN', true);
```

 

In this case, it returns an array of objects with the zone's name and its offset for the **current date and time**.

 

```
[
   { name: "Asia/Shanghai", offset: -480 },
   { name: "Asia/Urumqi", offset: -360 }
]
```

 

It's useful if you need to sort time zones by offset, but be aware that the offsets can change throughout the year.

 

All known country codes in the data can be retrieved using method `moment.tz.countries()`.

 

**Note:** Sometimes these methods might return unexpected data. See the [Countries and Zones guide](https://momentjs.com/timezone/guides/#/data-calculations/country-zones/) for more details.

     

## Zone Object

     

In order to match a timestamp to an offset, Moment Timezone uses a `Zone` object.

 

Though you shouldn't even need to use it, this object's constructor is available on the `moment.tz.Zone` namespace.

 

This object has 5 properties.

  

```
{
    name       : 'America/Los_Angeles',          // the unique identifier
    abbrs      : ['PDT', 'PST'],                 // the abbreviations
    untils     : [1414918800000, 1425808800000], // the timestamps in milliseconds
    offsets    : [420, 480],                     // the offsets in minutes
    population : 15000000                        // a rough population count for the largest city in this zone
}
```

     

###  Name 

    

```
zone.name; // America/Los_Angeles
```

  

The uniquely identifying name of the time zone. See the [IANA Time Zone database naming guidelines](https://data.iana.org/time-zones/theory.html#naming) for more details about the naming convention.

 

Note that the guidelines also say that these zone identifiers shouldn't be displayed directly to end users:

 

> Inexperienced users are not expected to select these names unaided. Distributors should provide documentation and/or a simple selection interface that explains each name via a map or via descriptive text like "Czech Republic" instead of the timezone name `"Europe/Prague"`.

 

Providing a full list of translated zone names for every locale is outside the scope of Moment Timezone. The [Unicode CLDR project](https://cldr.unicode.org/) contains locale-aware mappings for this purpose.

     

###  Abbreviation 

    

```
zone.abbr(timestamp); // PST
```

  

Get the abbreviation for a given timestamp (in milliseconds) from a `Zone`.

 

```
moment.tz.zone('America/Los_Angeles').abbr(1403465838805); // PDT
moment.tz.zone('America/Los_Angeles').abbr(1388563200000); // PST
```

     

###  Offset 

    

```
zone.utcOffset(timestamp); // 480
```

  

Get the offset for a given timestamp (in milliseconds) from a `Zone`.

 

```
moment.tz.zone('America/Los_Angeles').utcOffset(1403465838805); // 420
moment.tz.zone('America/Los_Angeles').utcOffset(1388563200000); // 480
```

 

POSIX compatibility requires that the offsets are inverted. Therefore, Etc/GMT-X will have an offset of `+X` and Etc/GMT+X will have an offset of `-X`. This is a result of IANA's [Time Zone Database](https://github.com/eggert/tz/blob/2017b/etcetera#L36-L42) and not an arbitrary choice by Moment.js. Thus, using locality based identifiers is preferred over fixed-offset identifiers.

 

This is also described on the [Wikipedia entry for the database](https://en.wikipedia.org/wiki/Tz_database#Area):

 

> The special area of "Etc" is used for some administrative zones, particularly for "Etc/UTC" which represents [Coordinated Universal Time](https://en.wikipedia.org/wiki/Coordinated_Universal_Time). In order to conform with the [POSIX](https://en.wikipedia.org/wiki/POSIX) style, those zone names beginning with "Etc/GMT" have their sign reversed from the standard [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601#Time_offsets_from_UTC) convention. In the "Etc" area, zones west of GMT have a positive sign and those east have a negative sign in their name (e.g "Etc/GMT-14" is 14 hours ahead of GMT).

 

For example, using the `Europe/Madrid` identifier gives a different result from `Etc/GMT+1`.

 

```
moment().tz('Etc/GMT+1').format('YYYY-MM-DD HH:mm ZZ');
// '2014-12-18 11:22 -0100'
moment().tz('Europe/Madrid').format('YYYY-MM-DD HH:mm ZZ');
// '2014-12-18 13:22 +0100'
```

     

###  Parse Offset 

    

```
zone.parse(timestamp); // 480
```

  

Parse an offset for a timestamp constructed from `Date.UTC` in that zone.

 

This is what Moment Timezone uses to parse input into a time zone. The process is conceptually similar to the following.

 

Assume we want to find the exact moment of `March 19 2014 8:30 am` in New York. Because the offset varies between `-04:00` and `-05:00` in New York, we don't know what the offset was on March 19th.

 

Instead, we create a timestamp in UTC and pass that to `zone.parse`, which will return the offset at that time.

 

```
var zone = moment.tz.zone('America/New_York');
zone.parse(Date.UTC(2012, 2, 19, 8, 30)); // 240
```

 

This is the code that handles the cases referenced in the [Parsing Ambiguities](#/using-timezones/parsing-ambiguous-inputs/) section above.

 

```
var zone = moment.tz.zone('America/New_York');
zone.parse(Date.UTC(2012, 2, 11, 1, 59)); // 300
zone.parse(Date.UTC(2012, 2, 11, 2, 0)); // 240
```

     

## Data Formats

     

Moment Timezone uses two data formats. An unpacked version for calculations and a packed version for minified transport.

     

###  Unpacked Format 

   

The unpacked format looks exactly like the [zone object](#/zone-object/).

 

The data below is for Los Angeles between 2014 and 2018.

  

```
{
    name       : 'America/Los_Angeles',
    abbrs      : ['PST', 'PDT','PST', 'PDT', 'PST', 'PDT', 'PST', 'PDT', 'PST', 'PDT', 'PST'],
    untils     : [1394359200000, 1414918800000, 1425808800000, 1446368400000, 1457863200000, 1478422800000, 1489312800000, 1509872400000, 1520762400000, 1541322000000, null],
    offsets    : [480, 420, 480, 420, 480, 420, 480, 420, 480, 420, 480],
    population : 15000000,
    countries  : ['US']
}
```

 

The lengths of `abbrs, untils, offsets` are all the same. The `offset` and `abbr` at any index are only active while the timestamp is less than the `until` at that index.

 

An easy way to read this aloud is *"between `untils[n-1]` and `untils[n]`, the abbr should be `abbrs[n]` and the offset should be `offsets[n]`"*.

 

Note that `untils` are measured in milliseconds and `offsets` are measured in minutes.

     

###  Packed Format 

   

The packed format represents an unpacked zone in a single string.

 

The data below is for Los Angeles between 2014 and 2018. More time zones can be seen in the [packed source file](https://github.com/moment/moment-timezone/blob/develop/data/packed/latest.json).

 

```
'America/Los_Angeles|PST PDT|80 70|01010101010|1Lzm0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0|15e6'
```

 

In order to save as many bytes as possible, we used a very compact format to store the data.

 

The data is split into 6 sections separated by pipes.

 

| # | Type | Example |
| --- | --- | --- |
| 0 | Name | `America/Los_Angeles` |
| 1 | Abbr Map | `PST PDT` |
| 2 | Offset Map | `80 70` |
| 3 | Abbr/Offset Index | `01010101010` |
| 4 | Timestamp Diff | `1Lzm0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0` |
| 5 | Population | `15e6` |

 

**Name:** The canonical name of the time zone.

 

**Abbr Map:** A space separated list of all the abbreviations ever used in this time zone.

 

**Offset Map:** A space separated list of all the offsets ever used in this time zone in minutes in base 60.

 

**Abbr/Offset Index:** A tightly packed array of indices into the offset and abbr maps. These are also in base 60.

 

**Timestamp Diffs:** This is where the timestamps are stored.

 

Because we are dealing with a sorted list of timestamps, we just store the diff from the last timestamps rather than storing the full timestamps.

 

The first item in the array is a unix timestamp in minutes. All items after the first item are numbers of minutes to be added to the previous value during unpacking. All items are stored in base 60.

 

As you may have seen from the example above, the timestamp diffs tend to duplicate the same values from year to year. These duplications allow gzip to compress the data even further than if we used full timestamps.

 

**Population:** The rough population size of the city that the zone is named after.

 

This is **not** in base 60, but instead uses scientific exponential notation. For example, a value of `15e6` means 15 * 106 (that's 15 with 6 zeros after it) and therefore represents the number `15,000,000`.

 

The value is only used to compare nearly-identical zones when using the [guess feature](#/using-timezones/guessing-user-timezone/), so it doesn't need to be precise.

 

Note that this value might be empty for some zones.

 

### Base 60?

 

You may be wondering why base 60 is used. Base 62 is a fairly common tool for ascii data compression, using `a-z` to represent `10-35` and `A-Z` to represent `36-61`.

 

While it may have saved a few bytes to use base 62, much of the data in Moment Timezone maps nicely to multiples of 60.

 

There are 60 minutes in an hour and 60 seconds in a minute. 3 hours is `30` minutes in base 60 and `300` seconds in base 60 instead of `180` and `10800` in base 10 or `2U` and `2Oc` in base 62.

     

###  Link Format 

   

In order to reduce duplication, the Moment Timezone data packer will create links out of two zones that share data that is exactly the same.

 

This data is the two zone names separated by a pipe.

 

```
moment.tz.add('America/Los_Angeles|PST PDT|80 70|01010101010|1Lzm0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0');
moment.tz.link('America/Los_Angeles|US/Pacific');
moment.tz("2013-12-01", "America/Los_Angeles").format(); // 2013-12-01T00:00:00-08:00
moment.tz("2013-12-01", "US/Pacific").format();          // 2013-12-01T00:00:00-08:00
```

     

## Data Loading

     

Once the data has been packed and transported to the client, it must be added to Moment Timezone.

 

This happens automatically in Node.js and the [pre-built bundles](https://momentjs.com/timezone/). If you're using a different loading method you might need to load the data yourself.

     

###  Adding a Zone 

    

```
moment.tz.add(PackedZoneString)
moment.tz.add(PackedZoneString[])
```

  

To add zone data to Moment Timezone, use `moment.tz.add`.

 

```
moment.tz.add('America/Los_Angeles|PST PDT|80 70|0101|1Lzm0 1zb0 Op0');
```

 

To add more than one zone, pass an array of packed data.

 

```
moment.tz.add([
    'America/Los_Angeles|PST PDT|80 70|0101|1Lzm0 1zb0 Op0',
    'America/New_York|EST EDT|50 40|0101|1Lz50 1zb0 Op0'
]);
```

 

**Note: The above zone data is sample data and is not up to date. Reference the [moment-timezone source](https://github.com/moment/moment-timezone/blob/develop/data/packed/latest.json) for up to date data.**

     

###  Adding a Link 

    

```
moment.tz.link(PackedLinkString)
moment.tz.link(PackedLinkString[])
```

  

To link two zone names to the same data, use `moment.tz.link`.

 

The strings passed in should be in the [link format](#/data-formats/link-format/): the two zone names separated by a pipe.

 

```
moment.tz.link('America/Los_Angeles|US/Pacific');
```

 

To add more than one link at a time, pass an array of link strings.

 

```
moment.tz.link([
    'America/Los_Angeles|US/Pacific',
    'America/New_York|US/Eastern'
]);
```

     

###  Loading a Data Bundle 

    

```
moment.tz.load({
    zones : [],
    links : [],
    version : '2014e'
});
```

  

The data for Moment Timezone comes from [the IANA Time Zone Database](https://www.iana.org/time-zones). New versions are released periodically as time zone laws change in various countries.

 

The versions are named after the year and an incrementing letter. `2014a 2014b 2014c...`

 

In order to keep versions together, Moment Timezone has a bundled object format as well.

  

```
{
    version : '2014e',
    zones : [
        'America/Los_Angeles|PST PDT|80 70|0101|1Lzm0 1zb0 Op0',
        'America/New_York|EST EDT|50 40|0101|1Lz50 1zb0 Op0'
    ],
    links : [
        'America/Los_Angeles|US/Pacific',
        'America/New_York|US/Eastern'
    ]
}
```

 

To load a bundle into Moment Timezone, use `moment.tz.load`.

  

```
moment.tz.load({
    version : '2014e',
    zones : [...],
    links : [...]
})
```

     

###  Checking Zone Existence 

    

```
moment.tz.zone(name); // Zone or null
```

  

To check if a zone exists, use `moment.tz.zone`. It will return the Zone if it was loaded and `null` if it was not loaded.

 

```
moment.tz.zone("UnloadedZone"); // null
moment.tz.add("UnloadedZone|UZ|0|0|");
moment.tz.zone("UnloadedZone"); // Zone { name : "UnloadedZone", ...}
```

     

###  Getting Zone Names 

    

```
moment.tz.names(); // String[]
```

  

To get a list of all available time zone names, use `moment.tz.names`.

 

```
moment.tz.names(); // ["Africa/Abidjan", "Africa/Accra", "Africa/Addis_Ababa", ...]
```

     

## Data Utilities

     

Because of the complexity of the packed and unpacked data formats, Moment Timezone has some heavily tested utility functions for working with the data.

 

Methods for unpacking data are included with the core library, as they are needed in order to use the library.

 

Methods for packing and subsetting the data are included in an additional `moment-timezone-utils.js` file. This file adds some more methods to the `moment.tz` namespace.

 

```
// in moment-timezone.js
moment.tz.unpack
moment.tz.unpackBase60
// in moment-timezone-utils.js
moment.tz.pack
moment.tz.packBase60
moment.tz.createLinks
moment.tz.filterYears
moment.tz.filterLinkPack
```

     

###  Pack 

    

```
moment.tz.pack(UnpackedObject); // PackedString
```

  

This converts data in the [unpacked format](#/data-formats/unpacked-format/) to the [packed format](#/data-formats/packed-format/).

 

```
var unpacked = {
    name       : 'Indian/Mauritius',
    abbrs      : ['LMT', 'MUT', 'MUST', 'MUT', 'MUST', 'MUT'],
    offsets    : [-230, -240, -300, -240, -300, -240],
    untils     : [-1988164200000, 403041600000, 417034800000, 1224972000000, 1238274000000, null],
    population : 150000
};
moment.tz.pack(unpacked); // "Indian/Mauritius|LMT MUT MUST|-3O -40 -50|012121|-2xorO 34unO 14L0 12kr0 11z0|15e4"
```

     

###  Unpack 

    

```
moment.tz.unpack(PackedString); // UnpackedObject
```

  

This converts data in the [packed format](#/data-formats/packed-format/) to the [unpacked format](#/data-formats/unpacked-format/).

 

```
var packed = "Indian/Mauritius|LMT MUT MUST|-3O -40 -50|012121|-2xorO 34unO 14L0 12kr0 11z0|15e4";

moment.tz.unpack(packed);
// {
//     name       : 'Indian/Mauritius',
//     abbrs      : ['LMT', 'MUT', 'MUST', 'MUT', 'MUST', 'MUT'],
//     offsets    : [-230, -240, -300, -240, -300, -240],
//     untils     : [-1988164200000, 403041600000, 417034800000, 1224972000000, 1238274000000, null],
//     population : 150000
// };
```

     

###  Pack Base 60 

    

```
moment.tz.packBase60(Number); // Base60String
```

  

Convert a base 10 number to a base 60 string.

 

```
moment.tz.packBase60(9);    // 9
moment.tz.packBase60(10);   // a
moment.tz.packBase60(59);   // X
moment.tz.packBase60(1337); // mh
```

 

Much like `Number.prototype.toFixed`, `moment.tz.packBase60` accepts a second argument for the number of digits of precision.

 

```
moment.tz.packBase60(1.1667,   1); // 1.a
moment.tz.packBase60(20.12345, 3); // k.7op
moment.tz.packBase60(59,       1); // X
```

 

A solitary `0` before the decimal point is dropped.

 

```
moment.tz.packBase60(1.1667, 1); // 1.a
moment.tz.packBase60(0.1667, 1); // .a
```

 

Trailing zeroes after the decimal point are dropped.

 

```
moment.tz.packBase60(1/6, 1); // .a
moment.tz.packBase60(1/6, 5); // .a
moment.tz.packBase60(59, 5);  // X
```

     

###  Unpack Base 60 

    

```
moment.tz.unpackBase60(Base60String); // Number
```

  

Convert a base 60 string to a base 10 number.

 

```
moment.tz.unpackBase60('9');     // 9
moment.tz.unpackBase60('a');     // 10
moment.tz.unpackBase60('X');     // 59
moment.tz.unpackBase60('mh');    // 1337
moment.tz.unpackBase60('1.9');   // 1.15
moment.tz.unpackBase60('k.7op'); // 20.123449074074074
```

     

###  Create Links 

    

```
moment.tz.createLinks(UnpackedBundle); // UnpackedBundle
```

  

In order to reduce duplication, we can create links out of two zones that share data.

  

```
var unlinked = {
    zones : [
        {name:"Zone/One",abbrs:["OST","ODT"],offsets:[60,120],untils:[403041600000,417034800000]},
        {name:"Zone/Two",abbrs:["OST","ODT"],offsets:[60,120],untils:[403041600000,417034800000]}
    ],
    links : [],
    version : "2014x-doc-example"
};

moment.tz.createLinks(unlinked);

{
    zones : [
        {name:"Zone/One",abbrs:["OST","ODT"],offsets:[60,120],untils:[403041600000,417034800000]}
    ],
    links : ["Zone/One|Zone/Two"],
    version : "2014x-doc-example"
}
```

 

This is especially useful when combined with `moment.tz.filterYears`, as older rules that would have differentiated two Zones may not be in the filtered year range, allowing them to be linked to save space.

     

###  Filter Years 

    

```
moment.tz.filterYears(UnpackedZone, Number, Number); // UnpackedZone
```

  

By default, Moment Timezone includes all the data from [the IANA Time Zone Database](https://www.iana.org/time-zones). This includes data from at least 1900 to 2038. Releases from version `0.5.37` onward include even more data, beyond the year 2400. The data for all these years may not be necessary for your use case.

 

`moment.tz.filterYears` can be used to filter out data for years outside a certain range.

  

```
var all    = { name : "America/Los_Angeles", abbrs : [...], offsets : [...] untils : [...]};
var subset = moment.tz.filterYears(all, 2012, 2016);
all.untils.length;    // 186
subset.untils.length; // 11
```

 

If only one year is passed, it will be used for the start and end year.

  

```
var all    = { name : "America/Los_Angeles", abbrs : [...], offsets : [...] untils : [...]};
var subset = moment.tz.filterYears(all, 2012);
all.untils.length;    // 186
subset.untils.length; // 3
```

 

Alternatively, one of the smaller pre-built [bundles available on the homepage](https://momentjs.com/timezone/) might already fit your needs.

     

###  Filter Years, Create Links, and Pack 

    

```
moment.tz.filterLinkPack(UnpackedBundle, Number, Number); // PackedBundle
```

  

The packing, link creation, and subsetting of years are all tools for compressing data to be transported to the client.

 

The `moment.tz.filterLinkPack` method combines all these into one simple interface. Pass in an unpacked bundle, start year, and end year and get a filtered, linked, packed bundle back.

 

This is what is being used to compress the output for the [bundled data + library files on the homepage](https://momentjs.com/timezone/).

  

    &copy; JS Foundation and other contributors
Licensed under the MIT License.

    [https://momentjs.com/timezone/docs/](https://momentjs.com/timezone/docs/)

--- METRICS ---
- Files Extracted: 2
- Estimated Token Budget: ~12052 tokens
- Recency Window: Active (< 180 days)
- Canonical Reference: https://codewiki.google/github.com/moment/moment-timezone
