[3] [[HTTP]] は、二種類の日付・時刻表現形式を定義しています。
一つは、絶対時刻表現 ([DFN[[CODE(ABNF)[[[HTTP-date]]]]]]) で、
更に細かく3つの形式に分けることができます。
もう一つは相対時刻表現 ([RUBY[Δ][デルタ]]秒) です。
本項では絶対時刻表現について扱います。

;; [75] 相対時刻表現については、[[デルタ秒]]を参照。

;; [140] [[HTTP]] の仕様書では、 [[HTTP]] 仕様で規定される[[ヘッダー]]内の日時の構文を定義していますが、
独自の[[ヘッダー]]を使用する場合や、 [[URL]] や [[payload]]
で独自に日時を記載する場合の構文を制限するものではありません。 [[HTML]]
では[[HTMLの日時形式]]が使われますし、 [[Web API]] などでは
[[Unix time]] などが使われることもあります。

* 仕様書

[REFS[
- [124] '''[CITE@en[RFC 7231 - Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content]] ([TIME[2014-08-07 05:54:02 +09:00]] 版) <https://tools.ietf.org/html/rfc7231#section-7.1.1.1>'''
- [8] [CITE@en[RFC 7231 - Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content]] ([TIME[2014-08-07 05:54:02 +09:00]] 版) <https://tools.ietf.org/html/rfc7231#appendix-A.3>
- 旧版
-- [76] [CITE@en[RFC 1945 - Hypertext Transfer Protocol -- HTTP/1.0]] ([TIME[2014-03-29 23:12:00 +09:00]] 版) <http://tools.ietf.org/html/rfc1945#section-3.3>
-- [112] 旧版 [CITE@en[RFC 2068 - Hypertext Transfer Protocol -- HTTP/1.1]] ([TIME[2014-03-24 01:18:13 +09:00]] 版) <http://tools.ietf.org/html/rfc2068#section-3.3.1>
-- [115] [CITE@en[RFC 2616 - Hypertext Transfer Protocol -- HTTP/1.1]] ([TIME[2014-03-19 19:51:21 +09:00]] 版) <http://tools.ietf.org/html/rfc2616#section-3.3.1>
-- [117] [CITE@en[RFC 2616 - Hypertext Transfer Protocol -- HTTP/1.1]] ([TIME[2014-03-19 19:51:21 +09:00]] 版) <http://tools.ietf.org/html/rfc2616#section-19.3>
- [21] [CITE@en[RFC 7234 - Hypertext Transfer Protocol (HTTP/1.1): Caching]] ([TIME[2014-09-11 10:19:59 +09:00]] 版) <https://tools.ietf.org/html/rfc7234#section-4.2>
- [31] [CITE@en[RFC 7234 - Hypertext Transfer Protocol (HTTP/1.1): Caching]] ([TIME[2014-09-11 10:19:59 +09:00]] 版) <https://tools.ietf.org/html/rfc7234#section-5.3>
- [33] [CITE@en[RFC 7089 - HTTP Framework for Time-Based Access to Resource States -- Memento]] ([TIME[2014-10-05 16:32:34 +09:00]] 版) <http://tools.ietf.org/html/rfc7089#section-2.1.1>
]REFS]

* 絶対時刻表現

[77] [[HTTP]] の [[RFC]] は、3つの[[日時形式]]を定義しています [SRC[>>76, >>112, >>115, >>124]]。
これらを総称して [DFN[[CODE(ABNF)@en[[[HTTP-date]]]]]] と呼ばれています [SRC[>>76, >>112, >>115, >>124]]。

[FIG(list)[
- [125] [DFN[[CODE(ABNF)@en[[[IMF-fixdate]]]]]]
-- [15] [[RFC 2616]] までの呼称は [DFN[[CODE(ABNF)@en[[[rfc1123-date]]]]]]: [[RFC 1123の日付形式]]
- [16] [DFN[[CODE(ABNF)@en[[[rfc850-date]]]]]]: [[RFC 850の日付形式]]
- [17] [DFN[[CODE(ABNF)@en[[[asctime-date]]]]]]: [[asctime形式]]
]FIG]

[78] このうち、 [[RFC 1123の日付形式]]が[RUBYB[好ましい]@en[preferred]] [SRC[>>76, >>112, >>115, >>124]]
とされています。

[116] [[RFC 1945]] では [[asctime形式]]の生成が禁止され、
[[RFC 2068]]/[[RFC 2616]]/[[RFC 7231]] [SRC[>>124]] では 
[[RFC 850の日付形式]]の[[生成]]も禁止されています。

[13] HTTP に限らず、様々なプロトコルや応用で、
日付と時刻を表現するために色々な方法が考えられてきました。
そのような状況下で HTTP 
は仕様が策定されたり実装されたりしてきたために、
それぞれが自分の好きな書式 (あるいは実装が楽な書式)
を採用していました。

HTTP RFC では、もっとも良く使われていた3つの書式
([Q[RFC 822 (RFC 1123 で改訂) 形式]],
[Q[RFC 850 形式]], [Q[asctime 形式]])
が公式に認められ、特に 822 の形式を推奨しています。
しかし、それ以外の書式にもできるだけ対応することもすすめています。

[80] これら3種類の形式を受け入れなければ[['''ならない''']] [SRC[>>76, >>112, >>115, >>124]] ですし、
他の[[プロトコル]]由来の[[日時]]にも対応できることが[RUBYB[勧められています]@en[encouraged]]
[SRC[>>76, >>112, >>115, >>124]]。

[10] ただし [CODE(HTTP)@en[[[If-Modified-Since:]]]] と 
[CODE(HTTP)@en[[[If-Unmodified-Since:]]]] の処理においては、
[CODE(ABNF)@en[[[HTTP-date]]]] でなければ無視しなければなりません 
([[条件付き要求]>>16]参照)。

[34] [[RFC 7089]] の [CODE(HTTP)@en[[[Accept-Datetime:]]]] と
[CODE(HTTP)@en[[[Memento-Datetime:]]]] は、 [[RFC 2616]] 
の [CODE(ABNF)@en[[[rfc1123-date]]]] の構文を[[コピペ]]して使っています。

;; [35] 意図は良くわかりませんが、 [[RFC 1123]] 形式以外は認めたくないということなのでしょうか。

* RFC 822 / RFC 1123 の日時形式

[4] [[RFC 822]] によって定義され、 [[RFC 1123]] によって改訂された形式の、
固定長の部分集合 [SRC[>>76, >>112, >>115]] とされています。[[RFC 822の日時形式]]として解釈可能な文字列ですが、
かなり制限されています。

;; [126] [[RFC 7231]] は [[RFC 5322の日時形式]]の部分集合 [SRC[>>124]] としていますが、
[[RFC 5322]] で生成が認められている構文の部分集合にはなっていません
(理解できなければならない構文の部分集合にはなっています)。

[FIG(railroad)[
= [[曜日]]
= [CODE[[[,]]]]
= [CODE[[[SP]]]]
= [[日]]
= [CODE[[[SP]]]]
= [[月]]名
= [CODE[[[SP]]]]
= [[年]]
= [CODE[[[SP]]]]
= [[時]]
= [CODE[[[:]]]]
= [[分]]
= [CODE[[[:]]]]
= [[秒]]
= [CODE[[[SP]]]]
= [CODE[[[GMT]]]]
]FIG]

[84] [[RFC 822]] における[[字句]]間の [[CFWS]] の自由な挿入は認められておらず、
[FIG(list)[
- [85] [[曜日]]の [CODE[[[,]]]] と[[日]]の間
- [86] [[日]]と[[月]]の間
- [87] [[月]]と[[年]]の間
- [88] [[年]]と[[時]]の間
- [89] [[秒]]と[[時間帯]]の間
]FIG]
... にだけ [CODE[[[U+0020]]]] 1文字だけを入れなければなりません [SRC[>>76, >>112, >>115, >>124]]。

[133] [[曜日]]は[[英語]]の先頭3文字です。 [[RFC 5322]] と同じものを採用しています [SRC[>>124]]。

[96] [[曜日]]は必須です [SRC[>>76, >>112, >>115, >>124]]。

;; [97] [[RFC 822]] では省略可能です。

[131] [[曜日]]は、 [[RFC 2616]] までは構文上[[大文字]]でも[[小文字]]でも良いことになっていましたが、
[[RFC 7231]] [SRC[>>124]] や [[RFC 7089]] [SRC[>>33]] は先頭のみ[[大文字]]で他は[[小文字]]の形に固定しています。

;; >>130

[90] [[日]]は2桁でなければなりません [SRC[>>76, >>112, >>115, >>124]]。

;; [91] [[RFC 822]] では1桁でも構いません。

;; [99] [[日]]の値域は明記されていません。

[134] [[月]]名は[[英語]]の先頭3文字です。 [[RFC 5322]] と同じものを採用しています [SRC[>>124]]。

[132] [[月]]名は、 [[RFC 2616]] までは構文上[[大文字]]でも[[小文字]]でも良いことになっていましたが、
[[RFC 7231]] [SRC[>>124]] や [[RFC 7089]] [SRC[>>33]] は先頭のみ[[大文字]]で他は[[小文字]]の形に固定しています。

;; >>130

[92] [[年]]は4桁でなければなりません [SRC[>>76, >>112, >>15, >>124]]。

;; [123] >>19 の方法で解釈すると1600年とそれ以前はエラーとなりますが、
[[HTTP]] の仕様上はそのような制約はありません。

[93] [[秒]]は省略できません [SRC[>>76, >>112, >>115, >>124]]。

[127] [[RFC 2616]] までは[[閏秒]]は表せないとしていましたが、
[[RFC 7231]] は[[閏秒]]も認めています [SRC[>>124]]。

;; [94] [[RFC 822]] は[[閏秒]]を認めていませんでしたが、 [[RFC 2822]] と
[[RFC 5322]] は認めています。

;; >>20

[95] [[時間帯]]は [CODE[[[GMT]]]] でなければなりません [SRC[>>76, >>112, >>115, >>124]]。

[129] [[時間帯]]は、 [[RFC 2616]] までは構文上[[大文字]]でも[[小文字]]でも構わないことになっていましたが、
[[RFC 7231]] は[[大文字]]のみ認めています [SRC[>>124]]。

;; >>130

;; [98] [[RFC 2822]] では [CODE[[[GMT]]]] の生成は認められておらず、 [CODE[[[+0000]]]]
としなければなりません。

* RFC 850 の日時形式

[12] [Q[[[RFC 850]] 形式]]とされているものは、 RFC 850 
によると [[ARPANET]] の日付形式であり、
[WEAK[(RFC 850 の他の部分から推察すると)]]
[[RFC 822の日付形式]]ではないかと思えますが、よく見ると RFC 822 
の形式とはやや異なり、その前の版である
[[RFC 733の日付形式]]に一致することが分かります。
ただし、 [[RFC 733]] は年号を4桁でも良いとしていますが、
HTTP の [Q[RFC 850 形式]]は2桁しか認めておらず、
この点で矛盾しています。

[79] この形式はよく用いられている [SRC[>>76, >>112, >>115]] とされていました。

[100] [[HTTP]] における [[RFC 1123の日付形式]]と似ていますが、
[FIG(list)[
- [101] [[曜日]]は[[英語]]の省略しない形でなければなりません [SRC[>>76, >>112, >>115, >>124]]。
- [102] [[月]]の前後は [[U+0020]] ではなく、 [CODE[[[-]]]] でなければなりません [SRC[>>76, >>112, >>115, >>124]]。
- [103] [[年]]は2桁でなければなりません [SRC[>>76, >>112, >>115, >>124]]。
]FIG]

[135] [[曜日]]は、 [[RFC 2616]] までは構文上[[大文字]]でも[[小文字]]でも良いことになっていましたが、
[[RFC 7231]] は先頭のみ[[大文字]]で他は[[小文字]]の形に固定しています [SRC[>>124]]。

;; >>130

[111] [[RFC 1945]]/[[RFC 2068]] では[[年]]の解釈は明記されていませんでした。

[118] [[RFC 2616]]/[[RFC 7231]] によれば、 50年よりも先のように解釈できる場合は、過去と解釈する[['''べき''']]としています
[SRC[>>117, >>124]]。

;; [122] この解釈は [[Cookieの日付形式]]と異なっています。 [[Webブラウザー]]の解釈を推測すると、
[[Cookieの日付形式]]の処理方法に従うべきかもしれません。

[113] この形式を生成しては[['''なりません''']] [SRC[>>112, >>115, >>124]]。

* asctime の日時形式

[104] この形式では[[曜日]]、[[U+0020]]、[[月]]、[[U+0020]]、[[日]]、[[U+0020]]、[[時刻]]、[[U+0020]]、
[[年]]の順に並べます [SRC[>>76, >>112, >>115, >>124]]。

[105] [[曜日]]と[[月]]と[[時刻]]は [[RFC 1123の日付形式]]と同じです [SRC[>>76, >>112, >>115, >>124]]。

[106] [[日]]は2桁の[[数字]]か、 [CODE[[[U+0020]]]] と1桁の[[数字]]で表します [SRC[>>76, >>112, >>115, >>124]]。
後者の場合、直前とあわせて [CODE[[[U+0020]]]] が2つ連続することになります。

;; [109] 1桁の数値の時どちらの形式を使うべきかは言及がありません。

;; [110] [[日]]の値域は明記されていません。

[107] [[年]]は、4桁の[[数字]]です [SRC[>>76, >>112, >>115, >>124]]。

[108] [[時間帯]]は明記しません。

[81] この形式を生成しては[['''なりません''']] [SRC[>>76, >>112, >>115, >>124]]。

* 時間帯

[82] [RUBY[[[時間帯]]][タイムゾーン]]は、 [[UTC]] [SRC[>>124]] (旧 [[GMT]] [SRC[>>76, >>112, >>115]]) 
でなければなりません。

[142] [[RFC 1123の日付形式]]と[[RFC 850の日付形式]]では
[CODE[[[GMT]]]] と表記します。

[83] [[asctime形式]]は[[時間帯]]の表記が含まれませんが、 [[GMT]]
と解釈しなければ[['''なりません''']] [SRC[>>76, >>112, >>115, >>124]]。

;;
[119] 指定されている[[時間帯]]が [[GMT]] でない場合、最も保守的な方法で [[GMT]]
に変換しなければ[['''ならない''']] [SRC[>>117]] というよくわからない規定が
[[RFC 2616]] にはありました。

[141] [[鯖]]や[[利用者エージェント]]は [[UTC]] 以外の[[地方時][地方標準時]]を使っているかもしれませんが、
[[HTTPの日時形式]]の[[生成]]と解釈においては必ず [[UTC]] を用いなければなりません。
もっとも、[[利用者エージェント]]が[[利用者]]に[[表示]]したり、
[[ログ]]に残したりする際には、任意の[[時間帯]]に変換しても構いません。

[25] [[キャッシュ]]である[[受信者]]は、[[時間帯]]の名前が
[CODE(HTTP)[GMT]] や [CODE(HTTP)@en[UTC]] 以外であれば、
[[満期時刻]]の計算においては[[日付]]は[[非妥当]]とみなす[['''べきです''']] [SRC[>>21]]。

[26] [CODE[UTC]] という値は仕様上歴史的にも認められていませんが、
実際には使われることがあるのでしょうか??

[47] >>26 実際に誤って使われた例があるみたいです。

;; [28] なぜ [['''SHOULD''']] なのかは謎です。

[27] [[キャッシュ]]である[[受信者]]は、
[[齢]]や[[満期時刻]]の計算や比較において[[地方時][地方標準時]]を影響させては[MUST[なりません]]
[SRC[>>21]]。

[36] [[大文字]]と[[小文字]]については >>130 参照。

* 大文字と小文字

[130] [[RFC 7231]] や [[RFC 7089]] の構文では[[小文字]]が一切認められていないので、
[[小文字]]で記述されていた場合に正しく解釈できないとしても適合する実装となります。

;; [22] [[RFC 2616]] までは [[ABNF]] で[[大文字]]でも[[小文字]]でも良いという定義になっていました。
[[RFC 723x]] における非互換変更ですが、理由の説明はありません。

[23] [[キャッシュ]]である[[受信者]]は、[[日]]、[[週]]、[[時間帯]]を[[大文字・小文字不区別]]とする[['''べきです''']]
[SRC[>>21]]。

;; [24] なぜ[[キャッシュ]]に限定されているのか謎です。

* 構文解析

[19] [[HTTP]] 仕様自体は [[HTTPの日付形式]]の構文解析の方法を規定していませんが、 [[Cookie]]
の仕様書である [[RFC 6265]] が [[Cookieの日付形式]]の構文解析の方法を規定しています。
[[RFC 6265]] 自体は [[Cookie]] について以外は何も述べていませんが、実際の[[利用者エージェント]]は
[[HTTP]] 全体で同じ構文解析ルーチンを使い回していることが多いでしょうから、 [[Cookie]]
以外の日付の解釈でもこの規定を流用できるでしょう。 ([[RFC 6265]] の構文解析法は 
[[HTTPの日付形式]]3種類すべてを正しく解釈できます。)

;; 詳しくは [[Cookieの日付形式]]の項をご覧下さい。

[29] [CODE(HTTP)@en[[[Expires:]]]] [[ヘッダー]]においては、
実装が [CODE(ABNF)@en[[[HTTP-date]]]] より低い精度の[[時刻]]しか扱えない場合に、
その[[時刻]]と同じかそれより前の直近の[[時刻]]によって内部的に表現しなければ[['''ならない''']]
[SRC[>>21]] とされています。

;; [30] [[秒]]単位が扱えないシステムが今時あるのかわかりませんが... ([[FAT]]
でしょうか...)

[32] [CODE(HTTP)@en[[[Expires:]]]] [[ヘッダー]]においては、
値が[[非妥当]]な時は過去の[[日時]]が指定されたものとすることになっています [SRC[>>31]]。

* 年

[64] [[RFC 2616]]/[[RFC 7231]] は2桁の[[年]]について、
その時点の年に基づき解釈を変えるようにと言っています。
詳しくは[[2桁西暦年号の解釈]]をご覧下さい。

[65] >>19 の構文解析法は1970年を固定の境界値にしています。

* 閏秒

[20] [[閏秒]]の扱いは明記されていません。構文上は秒を [[60]] や [[61]] としても適合しますが、
それを使っても良いとも悪いともされていません。

[114] [[RFC 2616]] までは [[ABNF]] 構文の[[注釈]]には範囲が 59 までとあり、
禁止されていたと解釈するのが適当でしょう。

[127] ところが [[RFC 7231]] は[[閏秒]]も認めています [SRC[>>124]]。

[62] >>19 の [[RFC 6265]] の構文解析法は[[閏秒]]に対応しておらず、解釈できない日付として扱います。

[63] 実際の[[利用者エージェント]]も [[Unix time]] や [[JavaScript]] [CODE(JS)@en[[[Date]]]]
など[[閏秒]]に対応していない内部形式で日付を保持・処理していることが多いでしょうから、
[[閏秒]]は扱えないと考えた方が安全です。

;; [128] [[HTML]] や [[JavaScript]] では[[閏秒]]を認めておらず、
[[Web platform]] の一体性を損なう [[RFC 7231]] の非互換変更です。
[[HTTP]] の人達は同じ [[IETF]] 内の [[RFC 5322]] の方が [[Web]]
よりも親近感があるようなのでそちらに揃えたのかもしれませんが...

* 文脈

[9] [[HTTPの日時形式]]は次の[[HTTPヘッダー]]で使われています。

[FIG(short list)[
- [CODE(HTTP)@en[[[Date:]]]]
- [CODE(HTTP)@en[[[Last-Modified:]]]]
- [CODE(HTTP)@en[[[If-Modified-Since:]]]]
- [CODE(HTTP)@en[[[If-Unmodified-Since:]]]]
- [CODE(HTTP)@en[[[If-Range:]]]]
- [CODE(HTTP)@en[[[Warning:]]]]
- [CODE(HTTP)@en[[[Accept-Datetime:]]]]
- [CODE(HTTP)@en[[[Memento-Datetime:]]]]
- [CODE(HTTP)@en[[[Link:]] ...; [[from]]]]
- [CODE(HTTP)@en[[[Link:]] ...; [[until]]]]
- [CODE(HTTP)@en[[[Link:]] ...; [[datetime]]]]
]FIG]

[39] 互換性のために必要な場合などを除き、新たに本日時形式を採用することは望ましくないと思われます。

;; [[HTMLの日時形式]]など、より近代的な方法を採用するべきでしょう。

[41] >>40 の [[Web API]] は [[RFC 1123]] 形式を採用しています。

[48] [[RAMLの日時形式]]は選択肢として [[RFC 2616]] を採用しています。

[REFS[
- [40] [CITE[はてなハイク API のデータの書式 - Hatena Developer Center]] ([TIME[2015-10-04 11:19:20 +09:00]] 版) <http://developer.hatena.ne.jp/ja/documents/haiku/apis/rest/datatypes#http-datetime>
]REFS]

* 変種

[5]
[[RFC 2069]] 『An Extension to HTTP : Digest Access Authentication』
は、 2069 の定義する認証関係のプロトコル要素内では [[RFC 1123]] 
形式のみを認めています。

[REFS[
- [120] [CITE@en[RFC 2069 - An Extension to HTTP : Digest Access Authentication]] ([TIME[2014-03-09 00:13:30 +09:00]] 版) <http://tools.ietf.org/html/rfc2069#page-8>
]REFS]

[121] [[RFC 2069]] が参照する [[RFC 2068]] は [[RFC 1123の日付形式]]以外の生成を認めていないので、
実質的に同じようにも思えますが、 [[RFC 1123の日付形式]]に適合しないものは解釈してはいけないという意図があるのでしょうか?

[6]
Netscape の原 [CODE(HTTP)[[[Cookie]]]] 提案では 
[CODE(HTTP)[[[expires]]]] 属性で使われる日付形式を
[Q[RFC 850 形式]]としています。 ([[RFC 2109]] <urn:ietf:rfc:2109> 
参照。) 現実にはいろいろ問題があります。
詳しくは [CODE(WikiPage)[[[Cookieの日付形式]]]]を参照してください。

;; [18] [[RFC 6265]] は [[HTTPの日付形式]]を使わなければならないと規定しています。

[7]
[[RFC 2518]] ([[WebDAV]]) では上記の [CODE(ABNF)[HTTP-Date]] と 
[[ISO 8601の日付形式]]を使い分けています。

;; [66] 後者は[[RFC 3339の日付形式]]を参照してください。

[72] [[HTTP]] から派生した [[RTSP]] は [[HTTPの日付形式]]をそのまま採用しています。

;; [73] [[RTSP]] は [[ISO 8601]] の[[プロファイル]]である [[utc-time]] や、
[[smpte-time]] や [[npt-time]] のような他の[[日時形式]]も用いています。

[74] [[HTTP]] から派生した [[MRCP]] は [[Cookie]] において [[RFC 1123の日付形式]]を採用しています。

[67] [[HTTP]] から派生した [[SIP]] は [[HTTPの日付形式]]のうち、 [[RFC 1123の日付形式]]のみ採用しています
[SRC[>>68, >>69]]。

[70] 第2版は[[大文字]]・[[小文字]]を区別すると述べています [SRC[>>69]]。

[REFS[
- [68] [CITE@en[RFC 2543 - SIP: Session Initiation Protocol]] ([TIME[2014-04-13 05:25:17 +09:00]] 版) <http://tools.ietf.org/html/rfc2543#section-6.18>
- [69] [CITE@en[RFC 3261 - SIP: Session Initiation Protocol]] ([TIME[2014-03-19 19:50:06 +09:00]] 版) <http://tools.ietf.org/html/rfc3261#section-20.17>
]REFS]

;; [71] なお [[SIP]] は [CODE[[[Timestamp:]]]] でこれとは別の[[時刻形式]]を定めています。

[43] [[XPath and XQuery Functions and Operators]] は [DFN[[CODE[fn:parse-ietf-date]]]]
なる[[関数]]を定義しています [SRC[>>42]]。「ietf-date」とは
[[RFC 2616]] の[[日時形式]]を想定していると注記があります [SRC[>>42]]。  

;; [44] [[RFC 3339の日時形式]]とは違うとも注記があります。設計時点から既に [[RFC 3339]]
はあったはずで、命名センスが無いですねぇ...

[45] 実際には独自の構文の定めがあり、細かく見ると微妙に [[HTTP]] と違っています。
[[HTTP]] の構文より認められる範囲が広かったり、
[[西暦2桁年号の解釈]]が違っていたりします。

[REFS[
- [42] [CITE@EN[XPath and XQuery Functions and Operators 3.1]]
([TIME[2017-03-21 16:02:06 +09:00]])
<https://www.w3.org/TR/2017/REC-xpath-functions-31-20170321/#func-parse-ietf-date>
]REFS]

[46] [[P3Pの日時形式]]

* HTTP におけるその他の日時形式

[37] [[PKP]] では、[[RFC 3339の日時形式]]を採用しています。

;; [CODE(URI)@en[[[report-uri]]]] を参照。

[38] [[HTTP]] で転送されるデータ ([[HTML]] など) では、それぞれの日時形式を採用しています。

* 歴史

[1] 古い HTTP/1.0 サーバーの形式(の1つ): 
[SAMP[Tue Nov 23 16:00:43 1993 GMT]]

;; [2] >>1 [[C]] の関数で返される形式ですかな。

[14] [[Apache]] は [[CGIスクリプト]]の出力する日付の形式を (少なくても [CODE(HTTP)@en[[[Last-Modified:]]]]
[[欄]]についてはチェックし、正しければその日付を、正しくなければ [[Unix epoch]] の日付を
[[RFC 1123]] 形式で出力します。この時、[[曜日]]が間違っていれば正しい値に直してくれます。

[FIG(quote)[
[FIGCAPTION[
RFC 1945 (HTTP/1.0); RFC 2068・2616 (HTTP/1.1) 3.3 Date/Time Formats
]FIGCAPTION]

[INS[
*RFC 2068・2616 3.3.1 Full Date
]INS]
>HTTP[DEL[/1.0 [INS[{1945}]]]] applications have historically allowed three different
formats for the representation of date/time stamps:

HTTP 応用は歴史的に日時を表す3つの書式を認めています。

>
-       [SAMP(HTTP)[Sun, 06 Nov 1994 08:49:37 GMT]]    ; RFC 822, updated by RFC 1123
-       Sunday, 06-Nov-94 08:49:37 GMT]]   ; RFC 850, obsoleted by RFC 1036
-       [SAMP(HTTP)[Sun Nov  6 08:49:37 1994]]         ; ANSI C's asctime() format

> The first format is preferred as an Internet standard and represents
a fixed-length subset of that defined by RFC 1123  (an update to
RFC 822). The second format is in common use, but is based on the
obsolete RFC 850  date format and lacks a four-digit year.
[DEL[[INS[{1945}]] HTTP/1.0]] [INS[[INS[{2068,2616}]] HTTP/1.1]] clients and servers that parse the date value
[DEL[[INS[{1945}]] should]] [INS[[INS[{2068,2616}]] MUST]] accept all three formats [INS[[INS[{2068,2616}]] (for compatibility with HTTP/1.0)]], though they [DEL[[INS[{1945}]] must never generate the third (asctime) format]] [INS[[INS[{2068,2616}]] MUST only generate the RFC 1123 format for representing HTTP-date values in header fields]].

最初の書式は Internet 標準で好ましいものであり、
RFC 1123 (RFC 822 の更新) で定義されるものの固定長部分集合です。
2番目の書式は広く使われていますが、廃止されている RFC 850 日付形式
で4桁の年号を表せません。
日付値を解析する HTTP クライアント及び鯖は、 [INS[(HTTP/1.0 との互換性のため、)]]
これら3つ全ての日付形式を受け付け[DEL[るべきです]][INS['''なければなりません''']]が、[DEL[3つ目の asctime 形式は生成してはなりません]][INS[頭欄内の [CODE(ABNF)[HTTP-date]] の値表現としては RFC 1123 形式のみを生成し'''なければなりません''']]。

> Note: Recipients of date values are encouraged to be robust in
accepting date values that may have been generated by non-HTTP
applications, as is sometimes the case when retrieving or posting
messages via proxies/gateways to SMTP or NNTP.

註: 日付値の受信者は非 HTTP 応用が生成したであろう日付値も
受け入れられるように柔軟であることを推奨します。記事を
SMTP や NNTP のプロキシや関門から記事を受け取ったり
投稿したりすることもあるからです。

> All HTTP[DEL[/1.0 [INS[{1945}]]]] date/time stamps [DEL[[INS[{1945}]] must]] [INS[[INS[{2068,2616}]] MUST]] be represented 
in [DEL[[INS[{1945}]] Universal Time (UT), also known as]] Greenwich Mean Time (GMT), 
without exception. [INS[[INS[{2616}]] For the purposes of HTTP, GMT is exactly equal to UTC (Coordinated Universal Time).]]
This is indicated in the first two formats by the inclusion of "GMT"
as the three-letter abbreviation for time zone, and [DEL[[INS[{1945}]] should]] [INS[[INS[{2068,2616}]] MUST]] be assumed when reading the asctime format. [INS[[INS[{2616}]] HTTP-date is case sensitive and MUST NOT include additional LWS beyond that specifically included as SP in the grammar.]]

全ての HTTP 日時印は例外無くグリニッジ標準時 (GMT)
で表されてい[DEL[る必要があります]][INS['''なければなりません''']]。 [INS[HTTP の範囲では、 GMT は UTC (協定世界時) と同じ物です。]]
これは「GMT」を時間帯の3文字略称として含めている最初の2つの書式
についてであり、 asctime 形式を読む時はそう仮定[DEL[すべきです]][INS['''しなければなりません''']]。[INS[[CODE(ABNF)[HTTP-date]] では大文字・小文字の区別は無く、文法で [CODE(ABNF)[SP]] が入ると示した場所以外で [CODE(ABNF)[LWS]] を含めては'''なりません'''。]]

>
[PRE(ABNF code)[
       HTTP-date      = rfc1123-date | rfc850-date | asctime-date

       rfc1123-date   = wkday "," SP date1 SP time SP "GMT"
       rfc850-date    = weekday "," SP date2 SP time SP "GMT"
       asctime-date   = wkday SP date3 SP time SP 4DIGIT

       date1          = 2DIGIT SP month SP 4DIGIT
                        ; day month year (e.g., 02 Jun 1982)
       date2          = 2DIGIT "-" month "-" 2DIGIT
                        ; day-month-year (e.g., 02-Jun-82)
       date3          = month SP ( 2DIGIT | ( SP 1DIGIT ))
                        ; month day (e.g., Jun  2)

       time           = 2DIGIT ":" 2DIGIT ":" 2DIGIT
                        ; 00:00:00 - 23:59:59

       wkday          = "Mon" | "Tue" | "Wed"
                      | "Thu" | "Fri" | "Sat" | "Sun"

       weekday        = "Monday" | "Tuesday" | "Wednesday"
                      | "Thursday" | "Friday" | "Saturday" | "Sunday"

       month          = "Jan" | "Feb" | "Mar" | "Apr"
                      | "May" | "Jun" | "Jul" | "Aug"
                      | "Sep" | "Oct" | "Nov" | "Dec"
]PRE]

> Note: HTTP requirements for the date/time stamp format apply
only to their usage within the protocol stream. Clients and
servers are not required to use these formats for user
presentation, request logging, etc.

註: HTTP は日時印形式をプロトコル列中での使用についてのみ
要求しています。クライアント及びサーバーは利用者への上演や
要求の記録などでこれらの形式を使う必要はありません。

[INS[
*RFC 2068・2616 (HTTP/1.1)  3.3.2 Delta Seconds
> Some HTTP header fields allow a time value to be specified as an
integer number of seconds, represented in decimal, after the time
that the message was received.

幾つかの HTTP 頭欄では、時刻値を、
メッセージを受信した時刻からの十進数で表現した整数値として指定することを認めています。

>
- delta-seconds  = 1*DIGIT
]INS]
]FIG]

[FIG(quote)[
[FIGCAPTION[
[139] RFC 1945 (HTTP/1.0) C.2; RFC 2068 (HTTP/1.1) 19.4.2; RFC 2616 (HTTP/1.1) 19.4.3 Conversion of Date Formats
]FIGCAPTION]

> [DEL[HTTP/1.0]] [INS[HTTP/1.1]] uses a restricted set of date formats (Section 3.3[INS[.1]]) to
simplify the process of date comparison. Proxies and gateways from
other protocols [DEL[should]] [INS[SHOULD]] ensure that any Date header field present in a
message conforms to one of the [DEL[HTTP/1.0]] [INS[HTTP/1.1]] formats and rewrite the date if necessary.

[11] [[HTTP/1.1]]
は[[日付形式]]の制限された集合を日付比較処理の簡素化のために使っています。
他のプロトコルからの串や関門はメッセージ中の Date
頭欄を HTTP/1.1 
形式のどれかに適合することを確認し、必要があれば日付を書き換える'''のが良い'''。

[INS[
注意: 修正点は RFC 1945 → RFC 2068 もの。
]INS]
]FIG]

[136] 歴史的には [[HTTP]] では各システムの既定の形式など様々な[[日時形式]]が用いられていたようですが、
そのうち最もよく使われていたらしい3形式だけが仕様書で明示的に対応を要求されています。

[137] 現在では [[HTTP]] [[鯖]]本体や[[利用者エージェント]]が[[生成]]する[[日時形式]]はほぼ
[[RFC 1123の日付形式]]に収束しているようです。 [TIME[2014-08-31T15:25:05.700Z]]

[138] 一方[[CGIスクリプト]]など[[鯖]]側の [[Webアプリケーション]]が[[生成]]することが多い
[[Cookie]] や [CODE(HTTP)@en[[[Expires]]]] などでは、依然、
非標準の日時形式が用いられることがあるようです。
[TIME[2014-08-31T15:25:07.900Z]]

