ISO 8601 と、日付を曖昧さなく書く方法
· 約 1 分
ISO 8601 が存在するのは、03/04/2026 がアメリカでは3月、それ以外では4月だからです。2026-04-03 と書けば曖昧さは消え、文字列として正しく並び、あらゆる API が受け付けるべき形になります。
03/04/2026 は世界の大半で4月3日、アメリカ合衆国では3月4日です。文字列だけからどちらの意味かを判じる方法はなく、どちらの読みもまったく理にかなっています。毎年この曖昧さが、守られなかった締切と二重予約、そして少なくともひとつの記憶に残る障害を生みます。
ISO 8601 は、それを取り除く国際規格です。
中心となる書式
2026-04-03T14:30:00Z
左から右へ、大きい単位から小さい単位へ読みます。
2026-04-03— 年、月、日。それぞれゼロ詰めで、常にこの順序T— 日付と時刻の区切り。厳密形では必須14:30:00— 24時間制の時、分、秒Z— ゾーン指示子。Zはちょうど UTC を意味する
順序こそが要点です。構成要素が上位から下位へ並ぶため、ISO 8601 の文字列は素のテキストとして正しく整列します。単純な文字列比較で 2026-04-03 は 2026-04-10 より前に来ます。ほかのどの一般的な書式にもできないことです。この性質だけでも規格の存在は正当化されます。
ゾーン指示子
有効な形は三つあり、意味はそれぞれ異なります。
| 形 | 意味 |
|---|---|
2026-04-03T14:30:00Z |
14:30 UTC。曖昧さなし |
2026-04-03T14:30:00+05:45 |
UTC より5時間45分進んだゾーンの現地時刻14:30。曖昧さなし |
2026-04-03T14:30:00 |
指定のないゾーンの14:30。タイムスタンプではない |
問題を起こすのは三つ目です。これは_現地日時_、つまり時間軸に置く手立てのない壁時計の読みです。これをシステム境界の向こうへ渡し、相手が自分と同じゾーンを仮定してくれると期待するのは、別のリージョンへのデプロイを待っている不具合です。
オフセットが何でないかにも注意してください。+05:45 はネパールのオフセットを示すのであって、そのタイムスタンプがネパールのものだとは示しません。オフセットはゾーンではありません。同じオフセットを複数のゾーンが共有し、ゾーンのオフセットは変わります。どこかを知る必要があるなら、識別子を並べて保持してください。
RFC 3339、おそらく必要なのはこちら
ISO 8601 は大きな規格です。週日付(2026-W14-5)、序数日付(2026-093)、小数単位、世紀を省く短縮形まで認めます。その大半は API で欲しいものではありません。
RFC 3339 はインターネット・プロトコル向けに引き締めた下位規定です。完全な日付を必須とし、ゾーン指示子を必須とし、区切りには T か空白のどちらかを認めます。API の文脈で「ISO 形式」と言う人は、ほぼ確実に RFC 3339 を指しています。
使える指針: よい構文解析器が受け付けるものは何でも受け取り、出すのは Z 付きの厳密な RFC 3339 だけにする。
期間と区間
使われる場面は少なめですが、出会ったときのために知っておく価値があります。
期間 は 「period」の P で始まり、T が日付部と時刻部を分けます。
P3Y6M4D— 3年6か月4日PT1H30M— 1時間30分P1DT12H— 1日12時間
T は省略できません。P1M は1か月、PT1M は1分です。ISO 8601 の期間にまつわる古典的な不具合がこれです。
区間 は二点をスラッシュで結びます。2026-04-03T14:00Z/2026-04-03T16:00Z、あるいは一点と期間で 2026-04-03T14:00Z/PT2H。
このサイトの HowTo 構造化データは期間の構文を使っています。2分の作業なら PT2M です。schema.org が ISO 8601 の期間を指定しているためです。
週日付と、そこに潜む罠
2026-W14-5 は2026年の第14 ISO 週の金曜日です。ISO 週は月曜に始まり、第1週は1月の最初の木曜を含む週です。
人がつまずく帰結はこれです。ISO の週年は暦年と常に一致するとはかぎりません。 2027年1月1日は2026年の第53 ISO 週に落ちます。ISO 週番号を暦年と組み合わせる整形コードは、毎年数日のあいだ誤った日付を吐きます。しかもたいていの言語で書式指定子はほとんど見分けがつきません(YYYY と GGGG、あるいは %Y と %G)。
実践的な規則
- UTC で保存し、
Zを付けて出す。2026-04-03T14:30:00Zはどこでも意味がひとつだけです。 - 裸の現地日時を境界の向こうへ出さない。 ゾーンを付けられないなら、それはタイムスタンプではありません。
- すべてゼロ詰めにする。
2026-4-3は有効な ISO 8601 ではありません。多くの構文解析器が受け入れるとしてもです。 - 区切りには
-と:を使う。 詰めた形(20260403T143000Z)は合法ですが不親切で、拒む構文解析器もあります。 - ゾーン識別子は別に保つ。 「どのオフセットか」ではなく「どこか」を知る必要があるときです。
Europe/Londonは規則変更を生き延び、+01:00は生き延びません。
構文解析の落とし穴
規格があってなお、崩れるのは構文解析のところです。
JavaScript の Date コンストラクタは ISO でない入力に対して一貫しません。 new Date('2026-04-03') は UTC の真夜中として解釈されます。new Date('2026-04-03T00:00:00') は——ゾーン指示子がないため——_現地_の真夜中として解釈されます。両者はあなたのオフセットぶん違い、つまり同じコードが動く場所によって別の日を返します。必ずゾーン指示子を付けてください。
二桁の年は曖昧であり、拒むべきです。 ISO 8601 は短縮形を認めますが、ほとんど何も受け入れるべきではありません。26-04-03 は1926年にも2026年にもなり、それを決める移動窓は構文解析器の中に隠れた方針判断です。
秒の小数部は精度がまちまちです。 14:30:00.5、14:30:00.500、14:30:00.500000 はいずれも有効で、いずれも同じ瞬間です。瞬間ではなく文字列を比較する構文解析器は、そう考えてくれません。
コンマは合法です。 ISO 8601 は 14:30:00,5 という小数コンマを認め、むしろ推奨します。たいていの構文解析器は拒みます。ヨーロッパのシステムからデータを受け取るなら覚悟しておいてください。
真夜中には綴りが二つあります。 ある日の 24:00:00 は翌日の 00:00:00 と同じ瞬間であり、どちらも有効な ISO 8601 です。出すのは後者にし、受け取るのは両方にしてください。
並べ替えについて
ISO 8601 の整列性が成り立つのは、ゾーン表現が同じ文字列どうしのあいだだけです。2026-04-03T14:00:00Z と 2026-04-03T10:00:00-05:00 は同じ瞬間ですが、文字列としては後者が先に並びます。
タイムスタンプをテキストとして並べるなら——ログファイル、ファイル名、テキスト型のデータベース列——まず全部を Z 付きの UTC に正規化してください。そうしないと、その順序は時間の性質ではなく書式の性質になります。