5. Date and Time format (日付と時刻の形式)
このセクションでは、日付と時刻の形式の望ましい品質について説明し、インターネット上で使用するためのISO 8601のプロファイルを定義します。
5.1. Ordering (順序付け)
日付と時刻のコンポーネントが最も精度の低いものから最も精度の高いものへと順序付けされている場合、有用な特性が達成されます。日付と時刻のタイムゾーンが同じであり(例:すべてUTC)、同じ文字列を使用して表現され(例:すべて"Z"またはすべて"+00:00")、すべての時刻が同じ数の小数秒桁を持つと仮定すると、日付と時刻の文字列は文字列としてソート(例:Cのstrcmp()関数を使用)でき、時間順のシーケンスが生成されます。オプションの句読点の存在は、この特性を損ないます。
例:
正しい順序(年-月-日 時:分:秒):
2002-01-15T10:00:00Z
2002-07-20T15:30:00Z
2002-12-31T23:59:59Z
誤った形式(月/日/年)は正しくソートできません:
01/15/2002 10:00:00
12/31/2002 23:59:59 ← 文字列ソートでは7月より前に配置される
07/20/2002 15:30:00
5.2. Human Readability (人間の可読性)
人間の可読性は、インターネットプロトコルの価値ある特徴であることが証明されています。人間が読めるプロトコルは、telnetがテストクライアントとして十分であることが多く、ネットワークアナライザーがプロトコルの知識で変更される必要がないため、デバッグのコストを大幅に削減します。一方、人間の可読性は、相互運用性の問題を引き起こすことがあります。
問題の例:
❌ "10/11/1996" はグローバル交換には完全に不適切
米国: 1996年10月11日
欧州: 1996年11月10日
❌ 月の略語の翻訳
英語: "Jan", "Feb", "Mar"
フランス語: "Jan", "Fév", "Mar" ← 相互運用性を損なう
すべての国の慣習に従って読める日付と時刻の形式は存在しないため、インターネットクライアントは、日付を地域に適した表示形式に変換する準備をしなければなりません(SHOULD)。これには、UTCをローカル時刻に変換することが含まれる場合があります。
5.3. Rarely Used Options (めったに使用されないオプション)
めったに使用されないオプションを含む形式は、相互運用性の問題を引き起こす可能性があります。これは、めったに使用されないオプションはアルファまたはベータテストで使用される可能性が低いため、解析のバグが発見される可能性が低いためです。相互運用性のために、めったに使用されないオプションは可能な限り必須にするか省略する必要があります。
以下に定義する形式には、めったに使用されないオプションが1つだけ含まれています:秒の小数部分 (Fractions of a Second)。これは、日付/時刻スタンプの厳密な順序付けを必要とするアプリケーションや、異常な精度要件を持つアプリケーションでのみ使用されることが予想されます。
5.4. Redundant Information (冗長情報)
日付/時刻形式に冗長情報が含まれている場合、冗長情報が相関しない可能性が導入されます。例えば、日付/時刻形式に曜日を含めると、曜日が間違っているが日付が正しい、またはその逆の可能性が導入されます。日付から曜日を計算することは難しくないため(付録Bを参照)、曜日は日付/時刻形式に含めるべきではありません。
問題の例:
❌ "Monday, 2002-07-16T10:00:00Z"
問題: 2002年7月16日は実際には火曜日で、月曜日ではありません
曜日と日付が一致しない場合、どちらを信頼すべきですか?
✅ "2002-07-16T10:00:00Z"
解決策: 曜日を省略し、必要に応じて計算します
5.5. Simplicity (簡潔性)
ISO 8601 [ISO8601] で指定されている日付と時刻の形式の完全なセットは、複数の表現と部分的な表現を提供しようとするため、非常に複雑です。付録Aには、ISO 8601の完全な構文をABNFに翻訳する試みが含まれています。インターネットプロトコルはやや異なる要件を持ち、簡潔性は重要な特性であることが証明されています。さらに、インターネットプロトコルは通常、真の相互運用性を達成するためにデータの完全な仕様を必要とします。したがって、ISO 8601の完全な構文は、ほとんどのインターネットプロトコルには複雑すぎると見なされます。
以下のセクションでは、インターネット上で使用するためのISO 8601のプロファイルを定義します。これはISO 8601拡張形式の一貫したサブセットです。簡潔性は、ほとんどのフィールドと句読点を必須にすることで達成されます。
5.6. Internet Date/Time Format (インターネット日付時刻形式)
以下のISO 8601 [ISO8601] 日付のプロファイルは、インターネット上の新しいプロトコルで使用されるべきです(SHOULD)。これは、[ABNF]で定義された構文記述表記を使用して指定されます。
ABNF構文定義
date-fullyear = 4DIGIT
date-month = 2DIGIT ; 01-12
date-mday = 2DIGIT ; 01-28, 01-29, 01-30, 01-31 based on
; month/year
time-hour = 2DIGIT ; 00-23
time-minute = 2DIGIT ; 00-59
time-second = 2DIGIT ; 00-58, 00-59, 00-60 based on leap second
; rules
time-secfrac = "." 1*DIGIT
time-numoffset = ("+" / "-") time-hour ":" time-minute
time-offset = "Z" / time-numoffset
partial-time = time-hour ":" time-minute ":" time-second
[time-secfrac]
full-date = date-fullyear "-" date-month "-" date-mday
full-time = partial-time time-offset
date-time = full-date "T" full-time
重要な注意事項
大文字小文字の区別: [ABNF]とISO8601に従い、この構文の"T"および"Z"文字は、それぞれ小文字の"t"または"z"を代替的に使用することもできます。
大文字小文字が重要な環境(XMLなど)でこの形式を使用する仕様は、日付時刻構文で使用される文字'T'と'Z'が常に大文字でなければならないように、日付時刻構文をさらに制限することができます(MAY)。この形式を生成するアプリケーションは大文字を使用すべきです(SHOULD)。
区切り文字: ISO 8601は、"T"で区切られた日付と時刻を定義しています。この構文を使用するアプリケーションは、可読性のために、(例えば)スペース文字で区切られたfull-dateとfull-timeを指定することを選択できます(MAY)。
形式の例
標準形式:
2002-07-15T10:30:00Z
2002-07-15T10:30:00.123Z
2002-07-15T10:30:00+08:00
2002-07-15T10:30:00-04:00
小数秒付き:
2002-07-15T10:30:00.123456Z
2002-07-15T10:30:00.52Z
可読性の高いバリアント(非標準だが許可):
2002-07-15 10:30:00Z
2002-07-15t10:30:00z
5.7. Restrictions (制限)
文法要素date-mdayは、現在の月内の日数を表します。最大値は月と年に基づいて変化します:
| 月番号 | 月/年 | 最大date-mday |
|---|---|---|
| 01 | 1月 (January) | 31 |
| 02 | 2月、平年 (February, normal) | 28 |
| 02 | 2月、閏年 (February, leap year) | 29 |
| 03 | 3月 (March) | 31 |
| 04 | 4月 (April) | 30 |
| 05 | 5月 (May) | 31 |
| 06 | 6月 (June) | 30 |
| 07 | 7月 (July) | 31 |
| 08 | 8月 (August) | 31 |
| 09 | 9月 (September) | 30 |
| 10 | 10月 (October) | 31 |
| 11 | 11月 (November) | 30 |
| 12 | 12月 (December) | 31 |
閏秒
文法要素time-secondは、閏秒が発生する月の末尾で値"60"を持つことができます(MAY)。閏秒は、UTCを地球の自転時刻に近づけるために使用されます。閏秒の詳細については、付録Dを参照してください。
閏秒の例:
1990-12-31T23:59:60Z ✅ 有効(1990年12月31日に閏秒が発生)
1990-12-31T23:59:61Z ❌ 無効(最大は60)
1990-06-15T23:59:60Z ❌ 無効(閏秒は月末のみ)
5.8. Examples (例)
以下は、有効なRFC 3339日付時刻スタンプの例です:
1985-04-12T23:20:50.52Z
表現: 1985年4月12日 23:20:50.52 UTC
1996-12-19T16:39:57-08:00
表現: 1996年12月19日 16:39:57 太平洋標準時(PST)
等価UTC: 1996-12-20T00:39:57Z
1990-12-31T23:59:60Z
表現: 1990年12月31日の閏秒
1990-12-31T15:59:60-08:00
表現: 1990年12月31日の閏秒、PSTで表現
等価UTC: 1990-12-31T23:59:60Z
1937-01-01T12:00:27.87+00:20
表現: 1937年1月1日 12:00:27.87、UTC+00:20
(歴史的タイムゾーンの例)
無効な例
❌ 1985-04-12 (時刻が欠落)
❌ 23:20:50.52Z (日付が欠落)
❌ 1985-04-12 23:20:50.52Z (スペースではなく'T'を使用すべき、ただし一部の実装は許可)
❌ 1985-04-32T23:20:50.52Z (無効な日付:4月に32日はない)
❌ 1985-02-29T23:20:50.52Z (無効な日付:1985年は閏年ではない)
実装の推奨事項: 常に標準形式を生成し('T'区切り文字と大文字の'Z'を使用)、寛容に解析します('t'、'z'、および場合によってはスペース区切り文字を受け入れる)。