Webシステムで多言語対応をするとき、サーバー側でTimeZoneを変換して、レンダーしてもいいのですが、ユーザーのTimeZoneをあらかじめ保存するなど、何かしらの方法でサーバーにTimeZoneを伝える必要があり、大変です。
そんなとき、ユーザーのクライアントのLocaleを利用すると便利です。
Moment.jsを利用して、それを表現する方法をご紹介します。
目次
Moment.jsはJavaScriptで時刻を扱うときに便利なライブラリです。時刻をフォーマットに従って表示したり、N時間後がいつかを計算したり、様々な時刻に関する計算が簡単に行えるようになります。
今回はTimeZoneを扱うので、TimeZoneについて拡張できるMomentTimezone.jsも同時に使っていこうと思います。
これらは、以下のようにパッケージマネージャーで簡単にインストールすることができます。
npm install moment-timezone
yarn add moment-timezone
もちろん、zipをダウンロードして、配置してもOKです。
今回は<time>
タグのdatetime
属性に時刻を入れたら、自動でクライアントのTimeZoneに合わせて時刻表示が変わるように作っています。
<!-- あらかじめdatetime属性にの値を入れておく -->
<time class="timezone" datetime="2022-01-01T00:00:00Z"></time>
<!-- moment.js, moment-timezone-with-data.jsをロード -->
<script src="script/moment.min.js"></script>
<script src="script/moment-timezone-with-data.min.js"></script>
<script>
// ここで"Asia/Tokyo"のような文字列が取れる!
var timezoneName = moment.tz.guess();
var elements = document.querySelectorAll('time.timezone');
var format = 'YYYY/MM/DD HH:mm:ss';
elements.forEach(function(el){
var dt = el.dateTime; // <time>タグのdatetime属性の値を取得
var timeStr = moment(dt).tz(timezoneName).format(format);
el.innerText = timeStr;
});
</script>
ポイントはmoment.tz.guess()
という部分です。ここで、Asia/Tokyo
のような文字列を取得できます。この機能はJavaScriptの国際化APIを利用して取得しているのですが、一部、国際化APIを利用できないブラウザでは他の情報から推測してTimeZoneを表示してくれるそうです。
MomentTimezone.jsのドキュメントを確認してみてください。
この文字列を利用してmoment(時刻).tz(timezoneName)
のようにすると、時刻のタイムゾーンを変更したデータを作ることができます。
サーバー側は時刻を気にせず実装することができるので、TimeZoneによるバグの心配なく安心して開発を進められます。
グローバル対応が必要なアプリケーションは比較的少ないからこそ、多言語対応やTimeZoneは分かりやすいやり方でやりたいですね。