Dayjsを利用する際にタイムゾーンの変換について毎回調べている気がするので記載しておく。
前提としてDayjsのデフォルトタイムゾーンをJST
としている。
import dayjs, { Dayjs } from 'dayjs';
import 'dayjs/locale/ja';
import timezone from 'dayjs/plugin/timezone';
import utc from 'dayjs/plugin/utc';
// UTCプラグインを読み込み
dayjs.extend(utc);
// timezoneプラグインを読み込み
dayjs.extend(timezone);
// 日本語化
dayjs.locale('ja');
// タイムゾーンのデフォルトをJST化
dayjs.tz.setDefault('Asia/Tokyo');
現在の日時をJSTで表現する
※現在日時 2024-05-28T22:06:53+09:00
の場合
OK
dayjs().tz().format();
// → 2024-05-28T22:06:53+09:00
dayjs().tz('Asia/Tokyo').format();
// → 2024-05-28T22:06:53+09:00
NG
ローカルタイムゾーンに依存するためJST
になるとは限らない
dayjs().format();
// → ローカルタイムゾーンに依存する
現在の日時をUTCで表現する
※現在日時 2024-05-28T22:08:35+09:00
の場合
dayjs().tz('utc').format();
// → 2024-05-28T13:08:35Z
与えたUTCの日時をJSTで表現する
与えたUTC日時が 2024-01-01 09:00:00
の場合
OK
dayjs.tz('2024-01-01 09:00:00', 'utc').tz().format();
// → 2024-01-01T18:00:00+09:00
dayjs.tz('2024-01-01 09:00:00', 'utc').tz('Asia/Tokyo').format();
// → 2024-01-01T18:00:00+09:00
NG
dayjs('2024-01-01 09:00:00').tz().format();
// → ローカルタイムゾーンに依存する
dayjs('2024-01-01 09:00:00').tz('Asia/Tokyo').format();
// → ローカルタイムゾーンに依存する
与えたUTC日時がISO8601
形式の 2024-01-01T09:00:00Z
の場合
(2024/05/29時点)ISO8601
形式の場合は注意が必要!
dayjs.tz(arg)
にISO8601形式の引数を渡すと、タイムゾーン情報を無視してUTC日時に変換されてしまうようです。
issueにも上がっているためバグなのではないかと思います。
https://github.com/iamkun/dayjs/issues/2626
OK
dayjs('2024-01-01T09:00:00Z').tz().format();
// → 2024-01-01T18:00:00+09:00
dayjs('2024-01-01T09:00:00Z').tz('Asia/Tokyo').format();
// → 2024-01-01T18:00:00+09:00
NG
※与えた日時がUTCなので問題が発生していないように見えますが…
dayjs.tz('2024-01-01T09:00:00Z', 'utc').tz().format();
// → 2024-01-01T18:00:00+09:00
dayjs.tz('2024-01-01T09:00:00Z', 'utc').tz('Asia/Tokyo').format();
// → 2024-01-01T18:00:00+09:00
与えたJSTの日時をUTCで表現する
与えたJST日時が 2024-01-01 09:00:00
の場合
OK
dayjs.tz('2024-01-01 09:00:00').tz('utc').format();
// → 2024-01-01T00:00:00Z
dayjs.tz('2024-01-01 09:00:00', 'Asia/Tokyo').tz('utc').format();
// → 2024-01-01T00:00:00Z
NG
dayjs('2024-01-01 09:00:00').tz('utc');
// → ローカルタイムゾーンに依存する
与えたJST日時がISO8601
形式の 2024-01-01T09:00:00+09:00
の場合
(2024/05/29時点)ISO8601
形式の場合は注意が必要!
dayjs.tz(arg)
にISO8601形式の引数を渡すと、タイムゾーン情報を無視してUTC日時に変換されてしまうようです。
issueにも上がっているためバグなのではないかと思います。
https://github.com/iamkun/dayjs/issues/2626
OK
dayjs('2024-01-01T09:00:00+09:00').tz('utc').format();
// → 2024-01-01T00:00:00Z
NG
-18:00
になってしまっている
dayjs.tz('2024-01-01T09:00:00+09:00', 'Asia/Tokyo').tz('utc').format();
// → 2023-12-31T15:00:00Z
まとめ
dayjs('2024-01-01 09:00:00')
- タイムゾーン情報なしの文字列の場合は、ローカルタイムゾーンで扱われる(動いているマシンのタイムゾーンに依存)
- 但し
ISO8601
形式の文字列を与えた場合はそのタイムゾーンとして扱われる
dayjs.tz('2024-01-01 09:00:00')
-
tz
の第2引数がない場合は、dayjs.tz.setDefault
で設定したデフォルトタイムゾーン扱いとなる
dayjs.tz('2024-01-01 09:00:00', 'Asia/Tokyo')
-
tz
の第2引数で指定したタイムゾーン扱いとなる
dayjs.tz('2024-01-01T09:00:00Z')
- 現時点(2024/05/29)では、UTC日時に強制的に変換されてしまうため、
dayjs('2024-01-01T09:00:00Z')
を利用すると良い