Skip to content

Latest commit

 

History

History
247 lines (176 loc) · 6.01 KB

contributing.md

File metadata and controls

247 lines (176 loc) · 6.01 KB

Bugs

If you are submitting a bug, please create a jsfiddle demonstrating the issue before opening a ticket on GitHub.

Contributing

Fork the library, install grunt, and install dependencies. Note that all pull requests will require a CLA.

npm install -g grunt-cli
npm install

Additions to moment-timezone.js or moment-timezone-utils.js should have matching tests in /tests/moment-timezone/.

Running tests

grunt nodeunit       # run all tests
grunt nodeunit:core  # run all core tests
grunt nodeunit:zones # run all zone tests

If all the tests are passing, submit a pull request.

Compiling data

There are several steps to compiling the timezone data. These have all been bundled into one grunt task to make releases easy.

Besides the node, npm, and grunt dependencies, there are also a few unix dependencies.

curl, tar, zic, and zdump are all required.

which curl tar zic zdump

To compile the latest iana release, run grunt data.

To compile a specific tagged release, run grunt data:2014d, replacing 2014d with the desired release tag.

The compilation process involves 7 steps. For each of the steps, a tag name can be passed to grunt. If no tag name was passed, it defaults to the latest release.

1. Download data from iana.org/time-zones.

grunt data-download:2014d

This downloads the data to temp/curl/2014d/data.tar.gz and unzips into temp/download/2014d.

2. Compile the data to a binary format using zic(8)

grunt data-zic:2014d

This compiles each of the source files in the temp/download/2014d folder to temp/zic/2014d.

3. Dump the changes from the binary format into a text format using zdump(8).

grunt data-zdump:2014d

This dumps a list of timezone changes for each zone in temp/zic/2014d to temp/zdump/2014d.

For each zone, print the time at the lowest possible time value, the time one day after the lowest possible time value, the times both one second before and exactly at each detected time discontinuity, the time at one day less than the highest possible time value, and the time at the highest possible time value.

via man zdump

4. Collect the changes into a single JSON file.

grunt data-collect:2014d

The output from zdump(8) looks like this.

America/Los_Angeles  Sun Mar  9 09:59:59 2014 UTC = Sun Mar  9 01:59:59 2014 PST isdst=0
America/Los_Angeles  Sun Mar  9 10:00:00 2014 UTC = Sun Mar  9 03:00:00 2014 PDT isdst=1
America/Los_Angeles  Sun Nov  2 08:59:59 2014 UTC = Sun Nov  2 01:59:59 2014 PDT isdst=1
America/Los_Angeles  Sun Nov  2 09:00:00 2014 UTC = Sun Nov  2 01:00:00 2014 PST isdst=0

The data-collect task takes all the dumped zones, converts them to moment-timezone's unpacked format, collects them into one object, and saves them to temp/collect/2014b.json.

    ...
}, {
    "name": "America/Los_Angeles",
    "abbrs": [..."PST", "PDT", "PDT", "PST"...],
    "untils": [...1604221199000, 1604221200000, 1615715999000, 1615716000000...],
    "offsets": [...480, 420, 420, 480...]
}, {
    "name": "America/Louisville",
    ...

5. Remove duplicate entries.

grunt data-dedupe:2014d

zdump(8) prints a line for the times one second before and exactly at each time discontinuity. In order to save space, we remove the one second before entries.

The output is saved in data/unpacked/2014d.json. This is the first file in the process that is committed to git. Steps 1-4 are stored in an ignored temp/ directory.

6. Pack the data into the compressed format.

grunt data-pack:2014d

Pack each zone in data/unpacked/2014d.json and save in data/packed/2014d.json.

// unpacked
{
    "name"    : "America/Phoenix",
    "abbrs"   : ["MST", "MDT", "MST", "MDT", "MST", "MWT", "MST", "MWT", "MST", "MDT", "MST"],
    "untils"  : [-1633273200000, -1615132800000, -1601823600000, -1583683200000, -880210800000, -820519140000, -812653140000, -796845540000, -84380400000, -68659200000, null],
    "offsets" : [420, 360, 420, 360, 420, 360, 420, 360, 420, 360, 420]
}

// packed
"America/Phoenix|MST MDT MWT|70 60 60|01010202010|-261r0 1nX0 11B0 1nX0 SgN0 4Al1 Ap0 1db0 SWqX 1cL0"

7. Extract zone & country meta data

grunt data-meta:2014d

This task creates a JSON file containing list of timezones and countries. The extracted meta data can be used to list all timezones, list all countries, and filter zones by a country.

The output is saved in data/meta/2014d.json

Sample output:

{
    "countries": {
        "AD": {
            "name": "Andorra",
            "abbr": "AD",
            "zones": [
                "Europe/Andorra"
            ]
        },
        "AE": {
            "name": "United Arab Emirates",
            "abbr": "AE",
            "zones": [
                "Asia/Dubai"
            ]
        },
        ...
    },
    "zones": {
        "Europe/Andorra": {
            "name": "Europe/Andorra",
            "lat": 42.5,
            "long": 1.5167,
            "countries": [
                "AD"
            ],
            "comments": ""
        },
        "Asia/Dubai": {
            "name": "Asia/Dubai",
            "lat": 25.3,
            "long": 55.3,
            "countries": [
                "AE",
                "OM"
            ],
            "comments": ""
        },
        ...
    }
}

8. Build tests for each zone.

grunt data-tests

This task does not support tagged releases, and is only run on the latest timezone data.

Reads data from temp/collect/latest.json and constructs unit tests for each zone. This uses temp/collect/latest.json instead of data/unpacked/latest.json in order to test both the times one second before and exactly at each time discontinuity.

All tasks

For sanity, all these tasks are bundled into one task. This is the preferred way to compile the data.

grunt data       # run tasks 1-8 on the latest release
grunt data:2014c # run tasks 1-7 on the 2014c release
grunt data:2014d # run tasks 1-7 on the 2014d release