💬

JavaScriptで扱う時間処理の基礎

2024/10/28に公開

時間の扱いをいつも忘れてしまうのでメモ📝

よく出てくる用語まとめ

用語 説明
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