はじめに
グローバルなアプリケーションだと、地域ごとにその地域にあったタイムゾーンで時間を表示したいケースがあります。実装の方針としては大きく分けて2つあり、バックエンドで日付を変換する方法とフロントエンドで日付を変換する方法です。
今回はセレクトボックスでタイムゾーンを選択するケースを想定し、フロントエンド側で日付を変換する方法としてMoment Timezoneを使った方法を紹介します。
Moment Timezone
Moment Timezone は日付の操作に関する様々な機能を提供するJavaScriptのライブラリです。サマータイムに対応しており、自動的に日付が補正されます。
セットアップ
パッケージマネージャとしてyarnを使い、Railsアプリケーションで使用する前提で説明します。まずは、moment-time-zone-with-dataをインストールします。
1 | $ yarn add moment-timezone-with-data |
次にRails側のロード処理をapplication.jsに追加します。
1 2 | //= require moment/moment //= require moment-timezone/builds/moment-timezone-with-data |
使用例
それでは、一般的な使い方を説明します。文字列からZone Objectを生成し、表示してみます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | // 第1引数で日付を第2引数でタイムゾーンを指定する。 var tokyo = moment.tz('2018-11-07 12:00:00', 'Asia/Tokyo'); // デフォルトのフォーマットで日付を表示する。 console.log(tokyo.format()); // 2018-11-07T12:00:00+09:00 // UTCに変換して表示する console.log(tokyo.utc().format()); // 2018-11-07T03:00:00Z // サマータイムは自動で補正されます var noSummer = moment.tz('2018-01-01 00:00:00', 'America/New_York'); console.log(noSummer.format()); // 2018-01-01T00:00:00-05:00 var summer = moment.tz('2018-04-01 00:00:00', 'America/New_York'); console.log(summer.format()); // 2018-04-01T00:00:00-04:00 |
Moment Timezoneの機能
Moment Timezoneの機能をいくつか紹介します。
タイムゾーンの一覧を表示する
Moment Timezoneで変換できるタイムゾーンの一覧は下記のように取得できます。
1 2 3 | console.log(moment.tz.names()); // (592) ["Africa/Abidjan", "Africa/Accra", "Africa/Addis_Ababa", "Africa/Algiers", // "Africa/Asmara", "Africa/Asmera", ...] |
現在のタイムゾーンを表示する
現在、自分がいる地域のタイムゾーンは下記のように取得できます。
1 2 | console.log(moment.tz.guess()); // Asia/Tokyo |
様々なフォーマットからパースする
Moment Timezoneでは様々なフォーマットからパースすることができます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | // 文字列から生成 var a = moment.tz('2018-11-07 12:00:00', 'Asia/Tokyo'); console.log(a.format()); // 2018-11-07T12:00:00+09:00 // 文字列から生成 var b = moment.tz("November 7th 2018 12PM", "MMM Do YYYY hA", "Asia/Tokyo"); console.log(b.format()); // 2018-11-07T12:00:00+09:00 // 配列から生成(+1ヶ月される) var c = moment.tz([2018, 11, 7, 12, 0, 0], "Asia/Tokyo"); console.log(c.format()); // 2018-12-07T12:00:00+09:00 // オブジェクトから生成(+1ヶ月される) var d = moment.tz({ year: 2018, month: 11, day: 7, hour: 12 }, 'Asia/Tokyo'); console.log(d.format()); // 2018-12-07T12:00:00+09:00 |
任意のタイムゾーンで日付を変換する
Zone Objectを別のタイムゾーンへ変換する方法は下記のとおりです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | var tokyo = moment.tz('2018-11-07 12:00:00', 'Asia/Tokyo'); console.log(tokyo.format()); // 2018-11-07T12:00:00+09:00 // タイムゾーンをAmerica/New_Yorkに変更して新たなZone Objectを作る var newYork = tokyo.clone().tz('America/New_York'); console.log(tokyo.format()); // 2018-11-07T12:00:00+09:00 console.log(newYork.format()); // 2018-11-06T22:00:00-05:00 // clone()しないと自分自身を変更する tokyo.tz('UTC'); console.log(tokyo.format()); // 2018-11-07T03:00:00Z |
フォーマットを指定して日付を表示する
Moment Timezoneでは指定したフォーマットで日付を出力することができます。
1 2 3 4 5 6 7 | tokyo.tz('UTC'); console.log(tokyo.format()); // 2018-11-07T03:00:00Z console.log(tokyo.format('Y/M/D HH:mm:ss')); // 2018/11/7 12:00:00 console.log(tokyo.format('Z z')); // +09:00 JST |
様々なパラメータを取得する
Zone Objectのパラメータの一部を紹介します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | var tokyo = moment.tz('2018-11-07 12:00:00', 'Asia/Tokyo'); // 日付を配列を取得 console.log(tokyo._a); // (7) [2018, 10, 7, 12, 0, 0, 0] // 日付を異なるフォーマットで取得 console.log(tokyo._d); // Wed Nov 07 2018 21:00:00 GMT+0900 (日本標準時) // Zone Objectの日付フォーマットを取得 console.log(tokyo._f); // YYYY-MM-DD HH:mm:ss // Zone Objectの日付フォーマットで日時を取得 console.log(tokyo._i); // 2018-11-07 12:00:00 // Unix Time Stampを取得 console.log(tokyo.unix()); // 1541559600 // Zone Objectが正常か console.log(tokyo.isValid()); // true var invalid = moment.tz('2018 00', 'Asia/Tokyo'); console.log(invalid.isValid()); // false |
さいごに
Moment Timezoneを使ってフロントエンドで任意のタイムゾーンに日付を変換する方法を紹介しました。