💬
JavaScriptで扱う時間処理の基礎
時間の扱いをいつも忘れてしまうのでメモ📝
よく出てくる用語まとめ
用語 | 説明 |
---|---|
UTC | 協定世界時(Coordinated Universal Time)の略称。世界の時刻の基準となる国際標準時。 |
GMT | UTCと同じと考えてOK。古い呼び名的な(詳しくは歴史的経緯が色々あるっぽいが)。 |
JST | タイムゾーン。Japanese Standard Time(日本標準時)。UTC+9の時間帯。 |
UNIX時間 | 1970年1月1日 00:00:00からの経過秒数。単なる整数として扱えるので計算が簡単。 |
エポックタイム | UNIX時間と同じと考えてOK。 |
ISO 8601(ISO形式) | 日付と時刻の表現方法を定めた国際規格。 |
ISO 8601フォーマット一覧
フォーマット | 例 | 説明 |
---|---|---|
日付(基本形式) | 20241028 | YYYYMMDDの8桁 |
日付(拡張形式) | 2024-10-28 | YYYY-MM-DDのハイフン区切り |
時刻(基本形式) | 134530 | hhmmssの6桁 |
時刻(拡張形式) | 13:45:30 | hh:mm:ssのコロン区切り |
日時(UTC) | 2024-10-28T13:45:30Z | 末尾のZはUTC時刻を示す |
日時(タイムゾーン付き) | 2024-10-28T13:45:30+09:00 | +/-hh:mmでタイムゾーンオフセットを示す |
週(拡張形式) | 2024-W44 | YYYY-Wxxで年と週番号を示す |
序数日付 | 2024-301 | YYYY-DDDで年と通算日(1-366)を示す |
APIからよく指定されるのは 2024-10-28T13:45:30Z
といった拡張形式が多い。
Dateオブジェクトの復習
引数の指定方法にはいくつかある。まず代表的なものを2つ。
// 未指定。現在時刻が取得される。
// Mon Oct 28 2024 20:24:40 GMT+0900 (日本標準時)
new Date()
// 年、月、時、分、秒、ミリ秒をそれぞれ整数で指定。年と月は必須。
// Sat Apr 04 1868 00:00:00 GMT+0918 (日本標準時)
new Date(1868, 3, 4)
そしてもうひとつUNIX時間。協定世界時(UTC)での1970年1月1日午前0時0分0秒からの経過ミリ秒を引数に渡すことができる。
// Thu Jan 01 1970 09:00:00 GMT+0900 (日本標準時)
new Date(0)
自分のMacのタイムゾーンが日本なので9時間が足されている。
そして最後のパターンは文字列。
// Sun Sep 01 2024 23:59:59 GMT+0900 (日本標準時)
new Date("2024-09-01T23:59:59+09:00")
これは扱いに注意が必要。文字列の解釈は環境ごとに異なる可能性があるため、基本的には利用しない。どうしても利用したい場合は、必ずタイムゾーンオフセットを指定すること。(👆のサンプルでいう+09:00
)
Dateオブジェクトの静的メソッド
2つある。
// 1730115442972
Date.now()
Date.now()
は現在の時刻に対応するUNIX時間を返す。
そしてもう1つ。
// Mon Sep 27 1920 09:00:00 GMT+0900 (日本標準時)
new Date(Date.UTC(1920, 8, 27))
Date.UTC()
は Date()
コンストラクタと同じ引数を取る。UTCでのその時刻に対応するUNIX時間を返す。
時刻の変換
const date = new Date()
// UTC時刻の取得
// Mon, 28 Oct 2024 12:08:58 GMT
date.toUTCString()
// ローカル時刻の取得(実行環境に依存)
// Mon Oct 28 2024 21:11:30 GMT+0900 (日本標準時)
date.toString()
// UTC時刻をISO形式で出力
// 2024-10-28T12:12:16.522Z
date.toISOString()
まとめ
個人的な肌感としてタイムゾーン操作をバニラJSでやるとバグを踏んでしまうケースが多い(使える!と思ったメソッドがブラウザ間で異なる結果を表示するケースがあったりする…❗)ので date-fns のようなライブラリを利用したほうが良いと思う。
あと日時操作には単体テストを書いたほうがよい❗️
テストが書きやすいコードにすべし。
追記: 最近踏んだ時間系のバグ
<input type="date" value="" />
日付入力フォームがChromeとSafariで見た目が違う。
プレースホルダーに今日の日付を入れてしまうSafariさん…やめて…
ブラウザ毎に見た目が変わってしまうので(挙動も変わるのか?)react-datepickerなどを素直に利用するのがいいと思った。ブラウザを信じない…。
Discussion