rfc1123-date

HTTP の日時形式

[3] HTTP は、二種類の日付・時刻表現形式を定義しています。 一つは、絶対時刻表現 (HTTP-date) で、 更に細かく3つの形式に分けることができます。 もう一つは相対時刻表現 (Δ (デルタ) 秒) です。 本項では絶対時刻表現について扱います。

[75] 相対時刻表現については、デルタ秒を参照。
[140] HTTP の仕様書では、 HTTP 仕様で規定されるヘッダー内の日時の構文を定義していますが、 独自のヘッダーを使用する場合や、 URL や payload で独自に日時を記載する場合の構文を制限するものではありません。 HTML ではHTMLの日時形式が使われますし、 Web API などでは Unix time などが使われることもあります。

仕様書

絶対時刻表現

[77] HTTP の RFC は、3つの日時形式を定義しています >>76, >>112, >>115, >>124。 これらを総称して HTTP-date と呼ばれています >>76, >>112, >>115, >>124。

[78] このうち、 RFC 1123の日付形式が好ましい (preferred) >>76, >>112, >>115, >>124 とされています。

[116] RFC 1945 では asctime形式の生成が禁止され、 RFC 2068/RFC 2616/RFC 7231 >>124 では RFC 850の日付形式の生成も禁止されています。

[13] HTTP に限らず、様々なプロトコルや応用で、 日付と時刻を表現するために色々な方法が考えられてきました。 そのような状況下で HTTP は仕様が策定されたり実装されたりしてきたために、 それぞれが自分の好きな書式 (あるいは実装が楽な書式) を採用していました。

HTTP RFC では、もっとも良く使われていた3つの書式 (RFC 822 (RFC 1123 で改訂) 形式, RFC 850 形式, asctime 形式) が公式に認められ、特に 822 の形式を推奨しています。 しかし、それ以外の書式にもできるだけ対応することもすすめています。

[80] これら3種類の形式を受け入れなければならない >>76, >>112, >>115, >>124 ですし、 他のプロトコル由来の日時にも対応できることが勧められています (encouraged) >>76, >>112, >>115, >>124。

[10] ただし If-Modified-Since: と If-Unmodified-Since: の処理においては、 HTTP-date でなければ無視しなければなりません (条件付き要求 (>>16)参照)。

[34] RFC 7089 の Accept-Datetime: と Memento-Datetime: は、 RFC 2616 の rfc1123-date の構文をコピペして使っています。

[35] 意図は良くわかりませんが、 RFC 1123 形式以外は認めたくないということなのでしょうか。

RFC 822 / RFC 1123 の日時形式

[4] RFC 822 によって定義され、 RFC 1123 によって改訂された形式の、 固定長の部分集合 >>76, >>112, >>115 とされています。RFC 822の日時形式として解釈可能な文字列ですが、 かなり制限されています。

[126] RFC 7231 は RFC 5322の日時形式の部分集合 >>124 としていますが、 RFC 5322 で生成が認められている構文の部分集合にはなっていません (理解できなければならない構文の部分集合にはなっています)。
  1. 曜日
  2. ,
  3. SP
  4. 日
  5. SP
  6. 月名
  7. SP
  8. 年
  9. SP
  10. 時
  11. :
  12. 分
  13. :
  14. 秒
  15. SP
  16. GMT

[84] RFC 822 における字句間の CFWS の自由な挿入は認められておらず、

... にだけ U+0020 1文字だけを入れなければなりません >>76, >>112, >>115, >>124。

[133] 曜日は英語の先頭3文字です。 RFC 5322 と同じものを採用しています >>124。

[96] 曜日は必須です >>76, >>112, >>115, >>124。

[97] RFC 822 では省略可能です。

[131] 曜日は、 RFC 2616 までは構文上大文字でも小文字でも良いことになっていましたが、 RFC 7231 >>124 や RFC 7089 >>33 は先頭のみ大文字で他は小文字の形に固定しています。

[90] 日は2桁でなければなりません >>76, >>112, >>115, >>124。

[91] RFC 822 では1桁でも構いません。
[99] 日の値域は明記されていません。

[134] 月名は英語の先頭3文字です。 RFC 5322 と同じものを採用しています >>124。

[132] 月名は、 RFC 2616 までは構文上大文字でも小文字でも良いことになっていましたが、 RFC 7231 >>124 や RFC 7089 >>33 は先頭のみ大文字で他は小文字の形に固定しています。

[92] 年は4桁でなければなりません >>76, >>112, >>15, >>124。

[123] >>19 の方法で解釈すると1600年とそれ以前はエラーとなりますが、 HTTP の仕様上はそのような制約はありません。

[93] 秒は省略できません >>76, >>112, >>115, >>124。

[127] RFC 2616 までは閏秒は表せないとしていましたが、 RFC 7231 は閏秒も認めています >>124。

[94] RFC 822 は閏秒を認めていませんでしたが、 RFC 2822 と RFC 5322 は認めています。

[95] 時間帯は GMT でなければなりません >>76, >>112, >>115, >>124。

[129] 時間帯は、 RFC 2616 までは構文上大文字でも小文字でも構わないことになっていましたが、 RFC 7231 は大文字のみ認めています >>124。

[98] RFC 2822 では GMT の生成は認められておらず、 +0000 としなければなりません。

RFC 850 の日時形式

[12] RFC 850 形式とされているものは、 RFC 850 によると ARPANET の日付形式であり、 (RFC 850 の他の部分から推察すると) RFC 822の日付形式ではないかと思えますが、よく見ると RFC 822 の形式とはやや異なり、その前の版である RFC 733の日付形式に一致することが分かります。 ただし、 RFC 733 は年号を4桁でも良いとしていますが、 HTTP の RFC 850 形式は2桁しか認めておらず、 この点で矛盾しています。

[79] この形式はよく用いられている >>76, >>112, >>115 とされていました。

[100] HTTP における RFC 1123の日付形式と似ていますが、

[135] 曜日は、 RFC 2616 までは構文上大文字でも小文字でも良いことになっていましたが、 RFC 7231 は先頭のみ大文字で他は小文字の形に固定しています >>124。

[111] RFC 1945/RFC 2068 では年の解釈は明記されていませんでした。

[118] RFC 2616/RFC 7231 によれば、 50年よりも先のように解釈できる場合は、過去と解釈するべきとしています >>117, >>124。

[122] この解釈は Cookieの日付形式と異なっています。 Webブラウザーの解釈を推測すると、 Cookieの日付形式の処理方法に従うべきかもしれません。

[113] この形式を生成してはなりません >>112, >>115, >>124。

asctime の日時形式

[104] この形式では曜日、U+0020、月、U+0020、日、U+0020、時刻、U+0020、 年の順に並べます >>76, >>112, >>115, >>124。

[105] 曜日と月と時刻は RFC 1123の日付形式と同じです >>76, >>112, >>115, >>124。

[106] 日は2桁の数字か、 U+0020 と1桁の数字で表します >>76, >>112, >>115, >>124。 後者の場合、直前とあわせて U+0020 が2つ連続することになります。

[109] 1桁の数値の時どちらの形式を使うべきかは言及がありません。
[110] 日の値域は明記されていません。

[107] 年は、4桁の数字です >>76, >>112, >>115, >>124。

[108] 時間帯は明記しません。

[81] この形式を生成してはなりません >>76, >>112, >>115, >>124。

時間帯

[82] 時間帯 (タイムゾーン) は、 UTC >>124 (旧 GMT >>76, >>112, >>115) でなければなりません。

[142] RFC 1123の日付形式とRFC 850の日付形式では GMT と表記します。

[83] asctime形式は時間帯の表記が含まれませんが、 GMT と解釈しなければなりません >>76, >>112, >>115, >>124。

[119] 指定されている時間帯が GMT でない場合、最も保守的な方法で GMT に変換しなければならない >>117 というよくわからない規定が RFC 2616 にはありました。

[141] 鯖や利用者エージェントは UTC 以外の地方時を使っているかもしれませんが、 HTTPの日時形式の生成と解釈においては必ず UTC を用いなければなりません。 もっとも、利用者エージェントが利用者に表示したり、 ログに残したりする際には、任意の時間帯に変換しても構いません。

[25] キャッシュである受信者は、時間帯の名前が GMT や UTC 以外であれば、 満期時刻の計算においては日付は非妥当とみなすべきです >>21。

[26] UTC という値は仕様上歴史的にも認められていませんが、 実際には使われることがあるのでしょうか??

[47] >>26 実際に誤って使われた例があるみたいです。

[28] なぜ SHOULD なのかは謎です。

[27] キャッシュである受信者は、 齢や満期時刻の計算や比較において地方時を影響させてはなりません >>21。

[36] 大文字と小文字については >>130 参照。

大文字と小文字

[130] RFC 7231 や RFC 7089 の構文では小文字が一切認められていないので、 小文字で記述されていた場合に正しく解釈できないとしても適合する実装となります。

[22] RFC 2616 までは ABNF で大文字でも小文字でも良いという定義になっていました。 RFC 723x における非互換変更ですが、理由の説明はありません。

[23] キャッシュである受信者は、日、週、時間帯を大文字・小文字不区別とするべきです >>21。

[24] なぜキャッシュに限定されているのか謎です。

構文解析

[19] HTTP 仕様自体は HTTPの日付形式の構文解析の方法を規定していませんが、 Cookie の仕様書である RFC 6265 が Cookieの日付形式の構文解析の方法を規定しています。 RFC 6265 自体は Cookie について以外は何も述べていませんが、実際の利用者エージェントは HTTP 全体で同じ構文解析ルーチンを使い回していることが多いでしょうから、 Cookie 以外の日付の解釈でもこの規定を流用できるでしょう。 (RFC 6265 の構文解析法は HTTPの日付形式3種類すべてを正しく解釈できます。)

詳しくは Cookieの日付形式の項をご覧下さい。

[29] Expires: ヘッダーにおいては、 実装が HTTP-date より低い精度の時刻しか扱えない場合に、 その時刻と同じかそれより前の直近の時刻によって内部的に表現しなければならない >>21 とされています。

[30] 秒単位が扱えないシステムが今時あるのかわかりませんが... (FAT でしょうか...)

[32] Expires: ヘッダーにおいては、 値が非妥当な時は過去の日時が指定されたものとすることになっています >>31。

年

[64] RFC 2616/RFC 7231 は2桁の年について、 その時点の年に基づき解釈を変えるようにと言っています。 詳しくは2桁西暦年号の解釈をご覧下さい。

[65] >>19 の構文解析法は1970年を固定の境界値にしています。

閏秒

[20] 閏秒の扱いは明記されていません。構文上は秒を 60 や 61 としても適合しますが、 それを使っても良いとも悪いともされていません。

[114] RFC 2616 までは ABNF 構文の注釈には範囲が 59 までとあり、 禁止されていたと解釈するのが適当でしょう。

[127] ところが RFC 7231 は閏秒も認めています >>124。

[62] >>19 の RFC 6265 の構文解析法は閏秒に対応しておらず、解釈できない日付として扱います。

[63] 実際の利用者エージェントも Unix time や JavaScript Date など閏秒に対応していない内部形式で日付を保持・処理していることが多いでしょうから、 閏秒は扱えないと考えた方が安全です。

[128] HTML や JavaScript では閏秒を認めておらず、 Web platform の一体性を損なう RFC 7231 の非互換変更です。 HTTP の人達は同じ IETF 内の RFC 5322 の方が Web よりも親近感があるようなのでそちらに揃えたのかもしれませんが...

文脈

[9] HTTPの日時形式は次のHTTPヘッダーで使われています。

[39] 互換性のために必要な場合などを除き、新たに本日時形式を採用することは望ましくないと思われます。

HTMLの日時形式など、より近代的な方法を採用するべきでしょう。

[41] >>40 の Web API は RFC 1123 形式を採用しています。

[48] RAMLの日時形式は選択肢として RFC 2616 を採用しています。

変種

[5] RFC 2069 『An Extension to HTTP : Digest Access Authentication』 は、 2069 の定義する認証関係のプロトコル要素内では RFC 1123 形式のみを認めています。

[121] RFC 2069 が参照する RFC 2068 は RFC 1123の日付形式以外の生成を認めていないので、 実質的に同じようにも思えますが、 RFC 1123の日付形式に適合しないものは解釈してはいけないという意図があるのでしょうか?

[6] Netscape の原 Cookie 提案では expires 属性で使われる日付形式を RFC 850 形式としています。 (RFC 2109 urn:ietf:rfc:2109 参照。) 現実にはいろいろ問題があります。 詳しくは Cookieの日付形式を参照してください。

[18] RFC 6265 は HTTPの日付形式を使わなければならないと規定しています。

[7] RFC 2518 (WebDAV) では上記の 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の日付形式のみ採用しています >>68, >>69。

[70] 第2版は大文字・小文字を区別すると述べています >>69。

[71] なお SIP は Timestamp: でこれとは別の時刻形式を定めています。

[43] XPath and XQuery Functions and Operators は fn:parse-ietf-date なる関数を定義しています >>42。「ietf-date」とは RFC 2616 の日時形式を想定していると注記があります >>42。

[44] RFC 3339の日時形式とは違うとも注記があります。設計時点から既に RFC 3339 はあったはずで、命名センスが無いですねぇ...

[45] 実際には独自の構文の定めがあり、細かく見ると微妙に HTTP と違っています。 HTTP の構文より認められる範囲が広かったり、 西暦2桁年号の解釈が違っていたりします。

[46] P3Pの日時形式

HTTP におけるその他の日時形式

[37] PKP では、RFC 3339の日時形式を採用しています。

report-uri を参照。

[38] HTTP で転送されるデータ (HTML など) では、それぞれの日時形式を採用しています。

歴史

[1] 古い HTTP/1.0 サーバーの形式(の1つ): Tue Nov 23 16:00:43 1993 GMT

[2] >>1 C の関数で返される形式ですかな。

[14] Apache は CGIスクリプトの出力する日付の形式を (少なくても Last-Modified: 欄についてはチェックし、正しければその日付を、正しくなければ Unix epoch の日付を RFC 1123 形式で出力します。この時、曜日が間違っていれば正しい値に直してくれます。

RFC 1945 (HTTP/1.0); RFC 2068・2616 (HTTP/1.1) 3.3 Date/Time Formats

RFC 2068・2616 3.3.1 Full Date

HTTP/1.0 {1945} applications have historically allowed three different formats for the representation of date/time stamps:

HTTP 応用は歴史的に日時を表す3つの書式を認めています。

  • 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
  • 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.

{1945} HTTP/1.0]] {2068,2616} HTTP/1.1 clients and servers that parse the date value
{1945} should]] {2068,2616} MUST accept all three formats {2068,2616} (for compatibility with HTTP/1.0), though they {1945} must never generate the third (asctime) format {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 クライアント及び鯖は、 (HTTP/1.0 との互換性のため、) これら3つ全ての日付形式を受け付けるべきですなければなりませんが、3つ目の asctime 形式は生成してはなりません頭欄内の 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/1.0 {1945} date/time stamps {1945} must {2068,2616} MUST be represented in {1945} Universal Time (UT), also known as Greenwich Mean Time (GMT), without exception. {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 {1945} should {2068,2616} MUST be assumed when reading the asctime format. {2616} HTTP-date is case sensitive and MUST NOT include additional LWS beyond that specifically included as SP in the grammar.

全ての HTTP 日時印は例外無くグリニッジ標準時 (GMT) で表されている必要がありますなければなりません。 HTTP の範囲では、 GMT は UTC (協定世界時) と同じ物です。 これは「GMT」を時間帯の3文字略称として含めている最初の2つの書式 についてであり、 asctime 形式を読む時はそう仮定すべきですしなければなりません。HTTP-date では大文字・小文字の区別は無く、文法で SP が入ると示した場所以外で LWS を含めてはなりません。

       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"

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 は日時印形式をプロトコル列中での使用についてのみ 要求しています。クライアント及びサーバーは利用者への上演や 要求の記録などでこれらの形式を使う必要はありません。

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

[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

HTTP/1.0 HTTP/1.1 uses a restricted set of date formats (Section 3.3.1) to simplify the process of date comparison. Proxies and gateways from other protocols should SHOULD ensure that any Date header field present in a message conforms to one of the HTTP/1.0 HTTP/1.1 formats and rewrite the date if necessary.

[11] HTTP/1.1 は日付形式の制限された集合を日付比較処理の簡素化のために使っています。 他のプロトコルからの串や関門はメッセージ中の Date 頭欄を HTTP/1.1 形式のどれかに適合することを確認し、必要があれば日付を書き換えるのが良い。

注意: 修正点は RFC 1945 → RFC 2068 もの。

[136] 歴史的には HTTP では各システムの既定の形式など様々な日時形式が用いられていたようですが、 そのうち最もよく使われていたらしい3形式だけが仕様書で明示的に対応を要求されています。

[137] 現在では HTTP 鯖本体や利用者エージェントが生成する日時形式はほぼ RFC 1123の日付形式に収束しているようです。

[138] 一方CGIスクリプトなど鯖側の Webアプリケーションが生成することが多い Cookie や Expires などでは、依然、 非標準の日時形式が用いられることがあるようです。