moment-timezoneを使用するには、[メールアドレス保護]+
、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
は含まれているため、必要ありません。
npm install moment-timezone
Node.jsでは、すべてのデータがプリロードされています。データの読み込みには追加のコードは必要ありません。
var moment = require('moment-timezone');
moment().tz("America/Los_Angeles").format();
ECMAScriptネイティブモジュール形式(またはTypeScript)の場合
import moment from 'moment-timezone';
moment().tz("America/Los_Angeles").format();
注記:基本的なmoment
ライブラリをrequire/importする必要はありません。Moment Timezoneは自動的にmoment
モジュールを読み込んで拡張し、変更されたインスタンスを返します。
npm
やyarn
などのパッケージマネージャーでは、複数のバージョンのmoment
がインストールされる場合があります。moment-timezone
からのみインポートすることで、同じバージョンが常に一貫して使用されるようにすることができます。潜在的なバージョン管理の問題を解決するための手順を含む、より詳細な説明については、issue #982に関するこのコメントを参照してください。
// Unnecessary, can cause issues with package managers
import moment from 'moment';
import 'moment-timezone';
// Correct
import moment from 'moment-timezone';
プリビルドバンドルはこちらはnpm
パッケージにも含まれており、直接ロードできます。これにより、より小さなデータサブセットを使用してライブラリをインポートできます。
import moment from 'moment-timezone/builds/moment-timezone-with-data-10-year-range.js'; // or .min.js
プリロードされたデータなしでライブラリのみをインポートすることもできます。
import moment from 'moment-timezone/moment-timezone.js'; // or .min.js
moment.tz.load(customData);
require.config({
paths: {
"moment": "path/to/moment"
}
});
define(["path/to/moment-timezone-with-data"], function (moment) {
moment().tz("America/Los_Angeles").format();
});
npm install moment-timezone
var moment = require('moment-timezone');
moment().tz("America/Los_Angeles").format();
注記:デフォルトでは、Webpackはすべてのmoment-timezoneデータ(moment-timezone 0.5.25では、900KB以上の縮小版)をバンドルします。不要なデータを削除し、必要なゾーンと日付範囲データのみをバンドルするには、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,
}),
],
};
あるいは、プリビルドバンドルもnpm
パッケージに含まれており、直接ロードできます。Node.jsセクションで詳細を参照してください。
また、Momentのバンドルされたロケールデータを削減する方法の例については、主要なMoment.js Webpackドキュメントも参照してください。これらの手法を組み合わせることで、最終的なバンドルサイズを大幅に削減できます(1MB以上の縮小版、または85KBの縮小版+gzip)。
Moment.jsでタイムゾーンを使用するためのインターフェースは2つあります。
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
この例では、最初にUTCでmoment.utc("2013-11-18 11:55")
オブジェクトを作成し、その後、指定されたタイムゾーンに変更します。これは、デフォルトのタイムゾーンでオブジェクトを作成した場合(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
サマータイムのため、時刻が存在しない場合や、2回存在する場合があります。
春、サマータイム開始時には、時計が1時間進みます。しかし実際には、時間が動いているのではなく、オフセットが動いているのです。
オフセットを前に進めることで、1時間が消えたという錯覚が生じます。時計の針が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はこれを考慮しています。存在しなかった時間を解析しようとすると、DSTのずれ分(通常は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
この例では、2時の時間は存在しないため、3時の時間と等価として扱われます。
秋、サマータイム終了時には、時計が1時間戻ります。これも、時間が逆戻りしているのではなく、オフセットだけが戻っているのです。この場合、1時間が繰り返されたという錯覚が生じます。
繰り返しますが、オフセットを含めると、何が実際に起こっているのかがより分かりやすくなります。
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
この情報は、1日の開始時刻の計算など、他の操作でも一貫して使用されます。
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
第2のパラメーターを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
これらの略語は、タイムゾーンオフセットによって変わる可能性があることに注意してください。これは、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
また、これらの略語はグローバルに一意ではないことに注意してください。以下に示すように、米国中部標準時と中国標準時は同じ略語を使用しています。
moment.tz('2016-01-01', 'America/Chicago').format('z'); // CST
moment.tz('2016-01-01', 'Asia/Shanghai').format('z'); // CST
moment#zoneAbbr
を使用して、ゾーンの略語を取得することもできます。これは、z
トークンをフォーマットする際にmoment.jsが使用するものです。
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などのサーバーのような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()
呼び出しは常に同じ値を返します。
オプションのブール引数「ignoreCache」を指定してmoment.tz.guess()
を呼び出すことができます。これを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"]
オフセットも取得するには、第2のパラメーターとして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
名前空間で使用できます。
このオブジェクトには5つのプロパティがあります。
{
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
}
zone.name; // America/Los_Angeles
タイムゾーンを一意に識別する名前です。命名規則の詳細については、IANAタイムゾーンデータベースの命名ガイドラインを参照してください。
ガイドラインでは、これらのゾーン識別子をエンドユーザーに直接表示しないように記述されていることにも注意してください。
経験の浅いユーザーがこれらの名前を無支援で選択することは想定されていません。配布者は、マップまたは「チェコ共和国」のようにタイムゾーン名「Europe/Prague」の代わりに説明的なテキストを使用して、各名前を説明するドキュメントや簡単な選択インターフェースを提供する必要があります。
すべてのロケールについて翻訳されたゾーン名の完全なリストを提供することは、Moment Timezoneの範囲外です。Unicode CLDRプロジェクトには、この目的のためのロケール対応マッピングが含まれています。
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のタイムゾーンデータベースの結果であり、Moment.jsによる任意の選択ではありません。したがって、固定オフセット識別子よりも、地域ベースの識別子の使用が推奨されます。
これはデータベースに関するWikipediaのエントリにも記載されています。
"Etc"の特別な領域は、特に協定世界時を表す"Etc/UTC"などの管理ゾーンに使用されます。POSIXスタイルに準拠するために、「Etc/GMT」で始まるゾーン名は、標準のISO 8601規則とは逆に符号が反転します。「Etc」領域では、GMTの西側のゾーンは正の符号を持ち、東側のゾーンは名前の中に負の符号を持ちます(例:「Etc/GMT-14」はGMTより14時間進んでいます)。
たとえば、Europe/Madrid
識別子を使用すると、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'
zone.parse(timestamp); // 480
そのゾーンでDate.UTC
から構築されたタイムスタンプのオフセットを解析します。
これは、Moment Timezoneがタイムゾーンに入力を解析するために使用する方法です。このプロセスは、概念的には次のものと似ています。
ニューヨークで2014年3月19日午前8時30分
の正確な瞬間を見つけたいと仮定します。ニューヨークではオフセットが-04:00
と-05:00
の間で変化するため、3月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は2つのデータ形式を使用します。計算用の展開形式と、圧縮された転送用の圧縮形式です。
展開形式は、ゾーンオブジェクトとまったく同じように見えます。
以下のデータは、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],
population : 15000000,
countries : ['US']
}
abbrs、untils、offsets
の長さはすべて同じです。任意のインデックスのoffset
とabbr
は、タイムスタンプがそのインデックスのuntil
よりも小さい間のみアクティブです。
これを簡単に説明すると、「untils[n-1]
とuntils[n]
の間は、abbrはabbrs[n]
、オフセットはoffsets[n]
になります」となります。
untils
はミリ秒単位で測定され、offsets
は分単位で測定されることに注意してください。
圧縮形式は、展開されたゾーンを1つの文字列で表します。
以下のデータは、2014年から2018年までのロサンゼルスのデータです。その他のタイムゾーンは、圧縮されたソースファイルで見ることができます。
'America/Los_Angeles|PST PDT|80 70|01010101010|1Lzm0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0|15e6'
できるだけ多くのバイト数を節約するために、非常にコンパクトな形式を使用してデータを保存しました。
データは、パイプで区切られた6つのセクションに分割されています。
# | タイプ | 例 |
---|---|---|
0 | 名前 | America/Los_Angeles |
1 | 略語マップ | PST PDT |
2 | オフセットマップ | 80 70 |
3 | 略語/オフセットインデックス | 01010101010 |
4 | タイムスタンプの差 | 1Lzm0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 |
5 | 人口 | 15e6 |
名前:タイムゾーンの標準名。
略語マップ:このタイムゾーンで使用されたすべての略語をスペースで区切ったリスト。
オフセットマップ:このタイムゾーンで使用されたすべてのオフセットを、60進数で分単位でスペースで区切ったリスト。
略語/オフセットインデックス:オフセットと略語マップへのインデックスを密に詰めた配列。これらも60進数です。
タイムスタンプの差:タイムスタンプが保存されている場所。
ソートされたタイムスタンプのリストを扱っているため、完全なタイムスタンプを保存するのではなく、最後のタイムスタンプからの差を保存するだけです。
配列の最初の要素は、分単位のUnixタイムスタンプです。最初の要素以降のすべての要素は、アンパック時に前の値に加算する分数を表します。すべての要素は60進数で格納されています。
上記の例で見たように、タイムスタンプの差分は、年々同じ値を繰り返す傾向があります。これらの重複により、完全なタイムスタンプを使用した場合よりも、gzipによるデータ圧縮率が向上します。
人口:ゾーンの名前の由来となった都市のおおよその人口。
これは60進数ではなく、科学的指数表記を使用しています。たとえば、値15e6
は15 * 106(15の後に6個のゼロが付いた数)を表し、数値15,000,000
を表します。
この値は、推測機能を使用する場合に、ほぼ同一のゾーンを比較するためにのみ使用されるため、正確である必要はありません。
一部のゾーンでは、この値が空の場合があることに注意してください。
なぜ60進数を使用するのか疑問に思われるかもしれません。62進数はASCIIデータ圧縮のための一般的なツールであり、a-z
を10-35
、A-Z
を36-61
として表します。
62進数を使用することで数バイト節約できたかもしれませんが、Moment Timezoneのデータの多くは60の倍数にきれいに対応しています。
1時間には60分、1分には60秒あります。3時間は、10進数では180
分、10800
秒、62進数では2U
分、2Oc
秒であるのに対し、60進数では30
分、300
秒となります。
重複を減らすために、Moment Timezoneデータパッカーは、まったく同じデータを持つ2つのゾーンからリンクを作成します。
このデータは、パイプで区切られた2つのゾーン名です。
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に追加する必要があります。
これはNode.jsとプリビルドバンドルでは自動的に行われます。別の読み込み方法を使用している場合は、自分でデータを読み込む必要があるかもしれません。
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[])
2つのゾーン名を同じデータにリンクするには、moment.tz.link
を使用します。
渡される文字列は、リンク形式である必要があります。つまり、パイプで区切られた2つのゾーン名です。
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],
population : 150000
};
moment.tz.pack(unpacked); // "Indian/Mauritius|LMT MUT MUST|-3O -40 -50|012121|-2xorO 34unO 14L0 12kr0 11z0|15e4"
moment.tz.unpack(PackedString); // UnpackedObject
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
// };
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
は、精度の桁数を指定する第2引数を受け入れます。
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
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
重複を減らすために、データが共通する2つのゾーンからリンクを作成できます。
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
と組み合わせると特に便利です。古いルールでは2つのゾーンを区別していた場合でも、フィルタリングされた年の範囲に含まれていない可能性があり、リンクすることで容量を節約できます。
moment.tz.filterYears(UnpackedZone, Number, Number); // UnpackedZone
デフォルトでは、Moment TimezoneにはIANAタイムゾーンデータベースのすべてのデータが含まれています。これには、少なくとも1900年から2038年までのデータが含まれています。バージョン0.5.37
以降のリリースには、2400年以降のデータも含まれています。これらの年のデータは、使用ケースによっては必要ない場合があります。
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
1つの年のみが渡された場合は、開始年と終了年として使用されます。
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
メソッドは、これらを1つのシンプルなインターフェースにまとめています。アンパックされたバンドル、開始年、終了年を渡すと、フィルタリングされ、リンクされ、パックされたバンドルが返されます。
これは、ホームページ上のバンドルされたデータとライブラリファイルの出力の圧縮に使用されている方法です。