HTTPの日時形式

HTTP の日時形式

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

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

仕様書

絶対時刻表現

[77] HTTPRFC は、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 7089Accept-Datetime:Memento-Datetime: は、 RFC 2616rfc1123-date の構文をコピペして使っています。

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

RFC 822 / RFC 1123 の日時形式

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

[126] RFC 7231RFC 5322の日時形式の部分集合 >>124 としていますが、 RFC 5322 で生成が認められている構文の部分集合にはなっていません (理解できなければならない構文の部分集合にはなっています)。
  1. 曜日
  2. ,
  3. SP
  4. SP
  5. SP
  6. SP
  7. :
  8. :
  9. SP
  10. 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 >>124RFC 7089 >>33 は先頭のみ大文字で他は小文字の形に固定しています。

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

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

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

[132] 名は、 RFC 2616 までは構文上大文字でも小文字でも良いことになっていましたが、 RFC 7231 >>124RFC 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 2822RFC 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+0020U+0020U+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] キャッシュである受信者は、時間帯の名前が GMTUTC 以外であれば、 満期時刻の計算においては日付非妥当とみなすべきです >>21

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

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

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

大文字と小文字

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

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

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

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

構文解析

[19] HTTP 仕様自体は HTTPの日付形式の構文解析の方法を規定していませんが、 Cookie の仕様書である RFC 6265Cookieの日付形式の構文解析の方法を規定しています。 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] 閏秒の扱いは明記されていません。構文上は秒を 6061 としても適合しますが、 それを使っても良いとも悪いともされていません。

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

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

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

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

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

文脈

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

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

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

[41] >>40Web APIRFC 1123 形式を採用しています。

変種

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

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

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

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

[7] RFC 2518 (WebDAV) では上記の HTTP-DateISO 8601の日付形式を使い分けています。

[66] 後者はRFC 3339の日付形式を参照してください。

[72] HTTP から派生した RTSPHTTPの日付形式をそのまま採用しています。

[73] RTSPISO 8601プロファイルである utc-time や、 smpte-timenpt-time のような他の日時形式も用いています。

[74] HTTP から派生した MRCPCookie において RFC 1123の日付形式を採用しています。

[67] HTTP から派生した SIPHTTPの日付形式のうち、 RFC 1123の日付形式のみ採用しています >>68, >>69

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

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

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

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

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

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] ApacheCGIスクリプトの出力する日付の形式を (少なくても 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アプリケーション生成することが多い CookieExpires などでは、依然、 非標準の日時形式が用いられることがあるようです。