はじめに
日時の表現はややこしい。特に手元の開発環境(PC)と実行環境(クラウドやコンテナ)でタイムゾーンが異なっていると厄介だ。
業務使っているTypeScript・luxonでどう書いたら何が返ってくるのかを備忘録としてまとめた。
実行環境
- Node 18.13.0
- TypeScript 5.0.4
- luxon 3.3.0
実行内容
前提:タイムゾーンの設定
Nodeのタイムゾーンは環境変数TZ
で設定できる。未設定の場合はホストマシンのタイムゾーンが使われている模様。
今回はpackage.jsonのスクリプトに直接記述する方法をとり、2つのコマンドの使い分けでタイムゾーンを変更できるようにした。
package.json
{
"scripts": {
"dev-jst": "TZ=Asia/Tokyo ts-node src/main.ts",
"dev-utc": "TZ=UTC ts-node src/main.ts"
}
}
src/main.ts
console.log(process.env.TZ);
実行結果
% pnpm run dev-jst
Asia/Tokyo
% pnpm run dev-utc
UTC
タイムゾーン情報なし
luxonにタイムゾーンの情報を与えていない場合、Nodeのタイムゾーンで出力される。
入力文字列にタイムゾーン情報が含まれている場合、入力文字列の時刻をNodeのタイムゾーンで表現したものが出力(※)される。
※toString
で出力される文字列
TZ=Asia/Tokyoの場合
const dtIso = DateTime.fromISO("2023-04-01T12:00:00");
const dtObj = DateTime.fromObject({ year: 2023, month: 4, day: 1, hour: 12 });
// -> 2023-04-01T12:00:00.000+09:00 (fromISO, fromObjectとも)
const dtWrittenInJst = DateTime.fromISO("2023-04-01T12:00:00+09:00");
// -> 2023-04-01T12:00:00.000+09:00
const dtWrittenInUtc = DateTime.fromISO("2023-04-01T12:00:00Z");
// -> 2023-04-01T21:00:00.000+09:00 ※UTCの12時はJSTの21時
TZ=UTCの場合
const dtIso = DateTime.fromISO("2023-04-01T12:00:00");
const dtObj = DateTime.fromObject({ year: 2023, month: 4, day: 1, hour: 12 });
// -> 2023-04-01T12:00:00.000+00:00 (fromISO, fromObjectとも)
const dtWrittenInJst = DateTime.fromISO("2023-04-01T12:00:00+09:00");
// -> 2023-04-01T03:00:00.000+00:00 ※JSTの12時はUTCの3時
const dtWrittenInUtc = DateTime.fromISO("2023-04-01T12:00:00Z");
// -> 2023-04-01T12:00:00.000+00:00
後からタイムゾーンのみ変更
インスタンス作成後にsetZone
でタイムゾーンを設定すると同じ絶対時刻で出力時のタイムゾーンのみを変えることができる。なお、setterのようなメソッド名だが実際には新しいインスタンスを返却する非破壊的なメソッドである。
TZ=Asia/Tokyoの場合
const dtIso = DateTime.fromISO("2023-04-01T12:00:00");
// -> 2023-04-01T12:00:00.000+09:00
const dtIsoToUtc = dtIso.setZone("utc");
// -> 2023-04-01T03:00:00.000Z ※JSTの12時はUTCの3時
TZ=UTCの場合
const dtIso = DateTime.fromISO("2023-04-01T12:00:00");
// -> 2023-04-01T12:00:00.000+00:00
const dtIsoToJst = dtIso.setZone("Asia/Tokyo");
// -> 2023-04-01T21:00:00.000+09:00 ※UTCの12時はJSTの21時
インスタンス生成時にタイムゾーンを指定
インスタンス生成時のオプションとしてzone
を指定すると、入力した日時の解釈と出力する文字列の両方にそのタイムゾーンが適用される。
TZに関わらず同じ結果
const dtJst = DateTime.fromISO("2023-04-01T12:00:00", { zone: "Asia/Tokyo" });
// -> 2023-04-01T12:00:00.000+09:00
const dtUtc = DateTime.fromISO("2023-04-01T12:00:00", { zone: "utc" });
// -> 2023-04-01T12:00:00.000Z