Spec-Zone.ru › Moment.js Timezone

Библиотека Moment.js с часовыми поясами

Где использовать

Для использования moment-timezone вам потребуется moment@2.9.0+, moment-timezone.js, и данные moment-timezone.

Для удобства на momentjs.com/timezone/ доступны сборки со всеми данными часовых поясов или их подмножеством.

  • moment-timezone-with-data.js рекомендуется для серверных сред (Node.js) и охватывает все доступные годы.
  • moment-timezone-with-data-10-year-range.js рекомендуется для большинства браузерных сред, охватывая +/- 5 лет с момента публикации.
  • moment-timezone-with-data-1970-2030.js охватывает 60-летний диапазон для тех, кому нужны дополнительные данные, но без большого размера файла с полными данными.

Если вы используете один из вышеперечисленных файлов, вам всё ещё понадобится moment.js, но moment-timezone.js вам не нужен, так как он включён.

Node.js

npm install moment-timezone

В Node.js все данные предварительно загружаются. Для загрузки данных не требуется дополнительный код.

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

Браузер

<script src="moment.js"></script>
<script src="moment-timezone-with-data.js"></script>

При использовании Moment Timezone в браузере вам также потребуется загрузить данные и библиотеку.

Вы можете либо использовать предварительно собранные библиотеку и файлы данных, ссылки на которые есть на главной странице, либо создать подмножество данных самостоятельно и загрузить его.

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();

Примечание: По умолчанию webpack объединяет все данные moment-timezone (в момент-timezone 0.5.25 это более 900 КБ в сжатом виде). Чтобы исключить ненужные данные и объединить только нужные данные зоны и диапазона дат, добавьте пакет moment-timezone-data-webpack-plugin:

// 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,
        }),
    ],
};

Также обратитесь к основному документации Moment.js для Webpack для примера по уменьшению объёма данных локали в Moment. Вместе эти техники могут значительно уменьшить окончательный объём сборки (более чем на 1 МБ в сжатом виде или на 85 КБ в сжатом + сжатом формате gzip).

Использование часовых поясов

Существует два интерфейса для использования часовых поясов с Moment.js.

moment.tz(..., String) выполняет разбор в заданном часовом поясе

Он принимает те же аргументы, что и конструктор moment, но использует последний аргумент в качестве идентификатора часового пояса:

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

Обратите внимание, что созданные моменты имеют разные значения UTC, поскольку эти моменты были созданы в разных часовых поясах.

moment().tz(String) выполняет преобразование в предоставленный часовой пояс

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

В этом примере вы сначала создаёте объект moment.utc("2013-11-18 11:55") в формате UTC, а затем изменяете его часовой пояс на указанный. Это также работает, если вы создаёте объект в вашем часовом поясе по умолчанию: moment("2013-11-18 11:55").

Обратите внимание, что созданные моменты имеют одинаковые значения UTC, так как эти моменты были созданы в по умолчанию часовом поясе.

Разбор в часовом поясе

moment.tz(..., String);

Конструктор moment.tz принимает все те же аргументы, что и конструктор moment, но использует последний аргумент в качестве идентификатора часового пояса.

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

Этот конструктор учитывает DST и будет использовать правильный смещение при разборе.

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

Смещение учитывается только при построении с массивом, строкой без смещения или объектом.

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

Если строка входных данных содержит смещение, оно используется вместо него для разбора. Затем полученный момент преобразуется в целевой часовой пояс.

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 и объекты Date ссылаются на конкретные моменты времени, поэтому смещение часового пояса не имеет смысла при построении. Использование moment.tz(Number|Date, zone) функционально эквивалентно 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

Вы можете указать булево значение сразу после аргумента формата, чтобы использовать строгий разбор. Строгий разбор требует точного соответствия формата и входных данных, включая разделители.

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

Разбор неоднозначностей

Из-за летнего времени существует возможность, что время либо не существует, либо существовало дважды.

Переход на летнее время

Весной, в начале летнего времени, часы переводят на один час вперёд. Однако на самом деле время не движется, а смещение меняется.

Перемещение смещения вперёд создаёт иллюзию исчезновения часа. По мере отсчёта времени вы можете увидеть, как оно переходит от 1:58 к 1:59 к 3:00. Проще увидеть, что происходит на самом деле, если включить смещение.

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

В результате любое время между 1:59:59 и 3:00:00 фактически никогда не происходило. Moment Timezone учитывает это. Если вы попытаетесь разобрать время, которое никогда не существовало, оно пропустит вперёд на величину разрыва летнего времени (обычно 1 час).

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

В этом примере час два не существует, поэтому он рассматривается как эквивалентный часу три.

Переход на зимнее время

Осенью, в конце летнего времени, часы переводят на один час назад. Опять же, время не движется назад, а меняется только смещение. В этом случае возникает иллюзия повторения часа.

Опять же, проще увидеть, что происходит на самом деле, если включить смещение.

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

Moment Timezone обрабатывает это, всегда используя более ранний экземпляр дублируемого часа.

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

Вы не сможете создать момент с более поздним экземпляром дублируемого часа, если не включите смещение при разборе.

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

Преобразование в часовой пояс

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

Мутатор moment#tz изменит часовой пояс и обновит смещение.

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

Эта информация последовательно используется в других операциях, например, при расчёте начала дня.

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

Без аргументов moment#tz возвращает:

  • имя часового пояса, назначенное экземпляру момента, или
  • undefined если часовой пояс не задан.
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

При передаче второго параметра как true, обновляются только часовой пояс (и смещение), при этом локальное время остаётся неизменным. Следовательно, он будет указывать на другой момент времени, если смещение изменилось.

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

Дополнения к форматированию

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

В дополнение к включению информации о форматировании +00:00, Moment Timezone также включает информацию об аббревиатуре часового пояса.

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

Обратите внимание, что эти аббревиатуры могут меняться в зависимости от смещения часового пояса. Это помогает различать смещения между местами, которые могут или могут не использовать летнее время.

// 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

Обратите также внимание, что эти аббревиатуры не являются глобально уникальными. Ниже вы можете видеть, что у Центрального стандартного времени США и Стандартного времени Китая одинаковая аббревиатура.

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

Вы также можете использовать moment#zoneAbbr для получения аббревиатуры часового пояса. Именно это использует moment.js при форматировании маркера z.

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

Moment.js также предоставляет плагин для имени часового пояса в полном формате. Поскольку эти строки обычно локализованы, Moment Timezone не предоставляет полные имена для поясов.

Чтобы предоставить полные имена, вы можете переопределить moment.fn.zoneName и использовать маркер zz.

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

Обратите внимание, что маркер форматирования z не всегда отображает аббревиатуру часового пояса, а вместо этого отображает смещение времени для каждого региона.

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)

Часовой пояс по умолчанию

moment.tz.setDefault(String);

По умолчанию объекты moment создаются в локальном часовом поясе.
Локальный часовой пояс — это часовой пояс, установленный в браузере или на вашем node.js сервере.

Чтобы изменить часовой пояс по умолчанию, используйте moment.tz.setDefault с допустимым часовым поясом.

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

Чтобы сбросить часовой пояс по умолчанию на локальный, используйте moment.tz.setDefault без аргументов.

moment.tz.setDefault();

Это глобальная настройка (общая для всех модулей).

Последующие вызовы moment.tz.setDefault не повлияют на существующие объекты moment или их копии.

Определение часового пояса пользователя

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

Moment Timezone использует API интернационализации (Intl.DateTimeFormat().resolvedOptions().timeZone) в поддерживаемых браузерах для определения часового пояса пользователя.

В других браузерах определение часового пояса является довольно сложной задачей, так как эти браузеры предоставляют мало информации. Для таких браузеров будет использоваться Date#getTimezoneOffset и Date#toString для нескольких моментов вокруг текущего года, чтобы собрать как можно больше информации о среде браузера. Затем эта информация сравнивается со всеми загруженными данными о часовых поясах, и возвращается ближайшее совпадение. В случае ничьей возвращается часовой пояс с городом с наибольшим населением.

По умолчанию Moment Timezone кэширует определённый часовой пояс. Это означает, что последующие вызовы moment.tz.guess() всегда будут возвращать то же значение.

Вы можете вызвать moment.tz.guess() с необязательным булевым аргументом "ignoreCache". Если он установлен в true, кэш будет проигнорирован и перезаписан новым значением.

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

Получение всех поясов

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

Чтобы получить список всех доступных названий часовых поясов, используйте moment.tz.names.

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

Получение поясов для страны

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

Чтобы получить список часовых поясов для какой-либо страны, используйте moment.tz.zonesForCountry().

moment.tz.zonesForCountry('US');

По умолчанию этот метод возвращает имена часовых поясов в алфавитном порядке:

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

Чтобы получить также смещения, передайте true в качестве второго параметра:

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

он возвращает массив объектов с именем и смещением:

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

Это полезно, если вам нужно отсортировать часовые пояса по смещению.

Все коды стран можно получить, используя метод moment.tz.countries()

Объект часового пояса

Для сопоставления отметки времени с смещением Moment Timezone использует объект Zone.

Хотя вам не нужно его использовать, конструктор этого объекта доступен в пространстве имён moment.tz.Zone.

У этого объекта есть 4 свойства.

{
    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
}

Имя

zone.name; // America/Los_Angeles

Уникальное идентифицирующее имя часового пояса.

Сокращение

zone.abbr(timestamp); // PST

Получить сокращение для заданной метки времени из Zone.

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

Смещение

zone.utcOffset(timestamp); // 480

Получить смещение для заданной метки времени (в мс) из Zone.

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

Совместимость с POSIX требует, чтобы смещения были инвертированы. Поэтому Etc/GMT-X будет иметь смещение +X, а Etc/GMT+X — смещение -X. Это результат базы данных часовых поясов IANA Time Zone Database, а не произвольный выбор Moment.js. Поэтому использование идентификаторов, основанных на местоположении, предпочтительнее идентификаторов с фиксированным смещением.

Например, 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. Следует использовать идентификатор Europe/Madrid, а не идентификатор Etc/GMT+1.

Разбор смещения

zone.parse(timestamp); // 480

Разбор смещения для метки времени, построенной из Date.UTC в данном часовом поясе.

Вот как Moment Timezone использует для разбора входных данных в часовой пояс. Процесс концептуально аналогичен следующему.

Предположим, мы хотим найти точный момент March 19 2014 8:30 am в Нью-Йорке. Поскольку смещение меняется между -04:00 и -05:00 в Нью-Йорке, мы не знаем, каково было смещение 19 марта.

Вместо этого мы создаём отметку времени в UTC и передаём её в zone.parse, который вернёт смещение в этот момент.

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

Это код, обрабатывающий случаи, упомянутые в разделе Разрешение неоднозначностей при парсинге выше.

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

Форматы данных

Moment Timezone использует два формата данных. Развернутый формат для вычислений и упакованный формат для сжатого транспорта.

Развернутый формат

Развернутый формат выглядит точно так же, как объект часового пояса.

Данные ниже относятся к Лос-Анджелесу в период с 2014 по 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]
}

Длины abbrs, untils, offsets одинаковы. offset и abbr в любом индексе активны только до тех пор, пока отметка времени меньше until в этом индексе.

Легкий способ прочитать это вслух: «Между untils[n-1] и untils[n] сокращение должно быть abbrs[n], а смещение — offsets[n]».

Обратите внимание, что untils измеряются в миллисекундах, а offsets — в минутах.

Упакованный формат

Упакованный формат представляет собой развернутый часовой пояс в одной строке.

Данные ниже относятся к Лос-Анджелесу в период с 2014 по 2018 год. Более подробную информацию о часовых поясах можно найти здесь.

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

Для экономии памяти мы использовали очень компактный формат хранения данных.

Данные разбиты на 5 разделов, разделенных символами «|».

# Тип Пример
0 Имя America/Los_Angeles
1 Карта сокращений PST PDT
2 Карта смещений 80 70
3 Индекс сокращений/смещений 01010101010
4 Разница отметок времени 1Lzm0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0

Имя: Каноническое имя часового пояса.

Карта сокращений: Список всех сокращений, когда-либо использовавшихся в этом часовом поясе, разделённые пробелами.

Карта смещений: Список всех смещений, когда-либо использовавшихся в этом часовом поясе в минутах в системе счисления по основанию 60, разделённые пробелами.

Индекс сокращений/смещений: Плотно упакованный массив индексов в карты смещений и сокращений. Они также представлены в системе счисления по основанию 60.

Разницы отметок времени: Здесь хранятся отметки времени.

Поскольку мы имеем дело с отсортированным списком отметок времени, мы просто храним разницу с последней отметкой времени, а не полные отметки времени.

Первый элемент в массиве — это отметка времени в Unix в минутах. Все элементы после первого элемента — это количество минут, которые необходимо добавить к предыдущему значению при распаковке. Все элементы хранятся в системе счисления по основанию 60.

Как вы могли видеть из примера выше, отметки времени с одинаковыми значениями часто повторяются из года в год. Эти повторы позволяют gzip сжимать данные ещё сильнее, чем если бы мы использовали полные отметки времени.

Система счисления по основанию 60?

Вы можете спросить, почему используется система счисления по основанию 60. Система счисления по основанию 62 — довольно распространённый инструмент для сжатия данных ASCII, используя a-z для представления 10-35 и A-Z для представления 36-61.

Хотя использование системы счисления по основанию 62 могло бы сэкономить несколько байтов, большая часть данных в Moment Timezone хорошо отображается на кратных 60.

В часе 60 минут, а в минуте 60 секунд. 3 часа составляют 30 минут в системе счисления по основанию 60 и 300 секунд в системе счисления по основанию 60 вместо 180 и 10800 в системе счисления по основанию 10 или 2U и 2Oc в системе счисления по основанию 62.

Формат ссылок

Для уменьшения дублирования пакетник данных Moment Timezone создаёт ссылки для двух часовых поясов, которые имеют идентичные данные.

Эти данные представляют собой два имени часовых поясов, разделённых символом «|».

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

Загрузка данных

После упаковки и передачи данных на клиент они должны быть добавлены в Moment Timezone.

Добавление часового пояса

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

Для добавления данных о часовом поясе в Moment Timezone используйте moment.tz.add.

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

Для добавления более одного часового пояса передайте массив упакованных данных.

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'
]);

Примечание: данные о часовом поясе выше — это примерные данные, и они не являются актуальными. Обратитесь к источнику moment-timezone для получения актуальных данных.

Добавление ссылки

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

Для связывания двух имён часовых поясов с одними и теми же данными используйте moment.tz.link.

Передаваемые строки должны быть в формате ссылки: два имени часовых поясов, разделённые символом «|».

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

Для добавления более одной ссылки одновременно передайте массив строк ссылок.

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

Загрузка пакета данных

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

Данные для Moment Timezone берутся из базы данных часовых поясов IANA. Новые версии выпускаются периодически по мере изменения законов о часовых поясах в различных странах.

Версии названы по году и увеличивающейся букве. 2014a 2014b 2014c...

Для сохранения версий вместе Moment Timezone также имеет объединённый формат объекта.

{
    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'
    ]
}

Для загрузки пакета в Moment Timezone используйте moment.tz.load.

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

Проверка существования часового пояса

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

Для проверки существования часового пояса используйте moment.tz.zone. Она вернёт часовой пояс, если он был загружен, и null, если он не был загружен.

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

Получение имён часовых поясов

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

Для получения списка всех доступных имён часовых поясов используйте moment.tz.names.

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

Утилиты данных

Из-за сложности упакованных и развернутых форматов данных Moment Timezone имеет ряд хорошо протестированных утилит для работы с данными.

Методы для распаковки данных включены в основной библиотеке, поскольку они необходимы для использования библиотеки.

Методы для упаковки и подмножества данных включены в дополнительный файл moment-timezone-utils.js. Этот файл добавляет дополнительные методы в пространство имён moment.tz.

// 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

Упаковка

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

Это преобразует данные в развернутом формате в упакованный формат.

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]
};
moment.tz.pack(unpacked); // "Indian/Mauritius|LMT MUT MUST|-3O -40 -50|012121|-2xorO 34unO 14L0 12kr0 11z0"

Распаковка

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

Это преобразует данные в упакованном формате в развернутый формат.

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

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]
// };

Упаковка по основанию 60

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

Преобразование числа в системе счисления по основанию 10 в строку в системе счисления по основанию 60.

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

Подобно Number.prototype.toFixed, moment.tz.packBase60 принимает второй аргумент для количества знаков после запятой.

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

Одиночное 0 перед десятичной точкой отбрасывается.

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

Конечные нули после десятичной точки отбрасываются.

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

Распаковка по основанию 60

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

Преобразование строки в системе счисления по основанию 60 в число в системе счисления по основанию 10.

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

Создание ссылок

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

Для уменьшения дублирования мы можем создавать ссылки для двух часовых поясов, которые имеют одинаковые данные.

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"
}

Это особенно полезно в сочетании с moment.tz.filterYears, поскольку более старые правила, которые отличали два часовых пояса, могут отсутствовать в отфильтрованном диапазоне лет, что позволяет связать их для экономии места.

Фильтрация лет

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

По умолчанию Moment Timezone включает все данные из базы данных часовых поясов IANA. Это включает данные с 1900 по 2038 год. Данные за все эти годы могут не потребоваться для вашего случая.

moment.tz.filterYears можно использовать для фильтрации данных за годы, выходящие за определённый диапазон.

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

Если передаётся только один год, он будет использован для начального и конечного года.

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

Фильтрация лет, создание ссылок и упаковка

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

Упаковка, создание ссылок и подмножество лет — это инструменты для сжатия данных для передачи на клиент.

Метод moment.tz.filterLinkPack объединяет все это в один простой интерфейс. Передайте распакованный пакет, начальный и конечный год, и получите отфильтрованный, связанный, упакованный пакет обратно.

Это используется для сжатия вывода для упакованных данных + файлов библиотеки на главной странице.

© JS Foundation and other contributors
Licensed under the MIT License.
https://momentjs.com/timezone/docs/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API