[3] HTTP は、二種類の日付・時刻表現形式を定義しています。
一つは、絶対時刻表現 (HTTP-date
) で、
更に細かく3つの形式に分けることができます。
もう一つは相対時刻表現 (Δ秒) です。
本項では絶対時刻表現について扱います。
[77] HTTP の RFC は、3つの日時形式を定義しています >>76, >>112, >>115, >>124。
これらを総称して HTTP-date
と呼ばれています >>76, >>112, >>115, >>124。
[78] このうち、 RFC 1123の日付形式が好ましい >>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 ですし、 他のプロトコル由来の日時にも対応できることが勧められています >>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
の構文をコピペして使っています。
[4] RFC 822 によって定義され、 RFC 1123 によって改訂された形式の、 固定長の部分集合 >>76, >>112, >>115 とされています。RFC 822の日時形式として解釈可能な文字列ですが、 かなり制限されています。
[84] RFC 822 における字句間の CFWS の自由な挿入は認められておらず、
U+0020
1文字だけを入れなければなりません >>76, >>112, >>115, >>124。[133] 曜日は英語の先頭3文字です。 RFC 5322 と同じものを採用しています >>124。
[96] 曜日は必須です >>76, >>112, >>115, >>124。
[131] 曜日は、 RFC 2616 までは構文上大文字でも小文字でも良いことになっていましたが、 RFC 7231 >>124 や RFC 7089 >>33 は先頭のみ大文字で他は小文字の形に固定しています。
[90] 日は2桁でなければなりません >>76, >>112, >>115, >>124。
[134] 月名は英語の先頭3文字です。 RFC 5322 と同じものを採用しています >>124。
[132] 月名は、 RFC 2616 までは構文上大文字でも小文字でも良いことになっていましたが、 RFC 7231 >>124 や RFC 7089 >>33 は先頭のみ大文字で他は小文字の形に固定しています。
[92] 年は4桁でなければなりません >>76, >>112, >>15, >>124。
[93] 秒は省略できません >>76, >>112, >>115, >>124。
[127] RFC 2616 までは閏秒は表せないとしていましたが、 RFC 7231 は閏秒も認めています >>124。
[95] 時間帯は GMT
でなければなりません >>76, >>112, >>115, >>124。
[129] 時間帯は、 RFC 2616 までは構文上大文字でも小文字でも構わないことになっていましたが、 RFC 7231 は大文字のみ認めています >>124。
[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。
[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つ連続することになります。
[82] 時間帯は、 UTC >>124 (旧 GMT >>76, >>112, >>115) でなければなりません。
[142] RFC 1123の日付形式とRFC 850の日付形式では
GMT
と表記します。
[83] asctime形式は時間帯の表記が含まれませんが、 GMT と解釈しなければなりません >>76, >>112, >>115, >>124。
[141] 鯖や利用者エージェントは UTC 以外の地方時を使っているかもしれませんが、 HTTPの日時形式の生成と解釈においては必ず UTC を用いなければなりません。 もっとも、利用者エージェントが利用者に表示したり、 ログに残したりする際には、任意の時間帯に変換しても構いません。
[25] キャッシュである受信者は、時間帯の名前が
GMT
や UTC
以外であれば、
満期時刻の計算においては日付は非妥当とみなすべきです >>21。
[26] UTC
という値は仕様上歴史的にも認められていませんが、
実際には使われることがあるのでしょうか??
[47] >>26 実際に誤って使われた例があるみたいです。
[130] RFC 7231 や RFC 7089 の構文では小文字が一切認められていないので、 小文字で記述されていた場合に正しく解釈できないとしても適合する実装となります。
[19] HTTP 仕様自体は HTTPの日付形式の構文解析の方法を規定していませんが、 Cookie の仕様書である RFC 6265 が Cookieの日付形式の構文解析の方法を規定しています。 RFC 6265 自体は Cookie について以外は何も述べていませんが、実際の利用者エージェントは HTTP 全体で同じ構文解析ルーチンを使い回していることが多いでしょうから、 Cookie 以外の日付の解釈でもこの規定を流用できるでしょう。 (RFC 6265 の構文解析法は HTTPの日付形式3種類すべてを正しく解釈できます。)
[29] Expires:
ヘッダーにおいては、
実装が HTTP-date
より低い精度の時刻しか扱えない場合に、
その時刻と同じかそれより前の直近の時刻によって内部的に表現しなければならない
>>21 とされています。
[32] Expires:
ヘッダーにおいては、
値が非妥当な時は過去の日時が指定されたものとすることになっています >>31。
[64] RFC 2616/RFC 7231 は2桁の年について、 その時点の年に基づき解釈を変えるようにと言っています。 詳しくは2桁西暦年号の解釈をご覧下さい。
[20] 閏秒の扱いは明記されていません。構文上は秒を 60 や 61 としても適合しますが、 それを使っても良いとも悪いともされていません。
[114] RFC 2616 までは ABNF 構文の注釈には範囲が 59 までとあり、 禁止されていたと解釈するのが適当でしょう。
[127] ところが RFC 7231 は閏秒も認めています >>124。
[62] >>19 の RFC 6265 の構文解析法は閏秒に対応しておらず、解釈できない日付として扱います。
[63] 実際の利用者エージェントも Unix time や JavaScript Date
など閏秒に対応していない内部形式で日付を保持・処理していることが多いでしょうから、
閏秒は扱えないと考えた方が安全です。
[9] HTTPの日時形式は次のHTTPヘッダーで使われています。
[39] 互換性のために必要な場合などを除き、新たに本日時形式を採用することは望ましくないと思われます。
[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の日付形式
を参照してください。
[7]
RFC 2518 (WebDAV) では上記の HTTP-Date
と
ISO 8601の日付形式を使い分けています。
[72] HTTP から派生した RTSP は HTTPの日付形式をそのまま採用しています。
[74] HTTP から派生した MRCP は Cookie において RFC 1123の日付形式を採用しています。
[67] HTTP から派生した SIP は HTTPの日付形式のうち、 RFC 1123の日付形式のみ採用しています >>68, >>69。
[70] 第2版は大文字・小文字を区別すると述べています >>69。
[43] XPath and XQuery Functions and Operators は fn:parse-ietf-date
なる関数を定義しています >>42。「ietf-date」とは
RFC 2616 の日時形式を想定していると注記があります >>42。
[45] 実際には独自の構文の定めがあり、細かく見ると微妙に HTTP と違っています。 HTTP の構文より認められる範囲が広かったり、 西暦2桁年号の解釈が違っていたりします。
[37] PKP では、RFC 3339の日時形式を採用しています。
report-uri
を参照。[1] 古い HTTP/1.0 サーバーの形式(の1つ): Tue Nov 23 16:00:43 1993 GMT
[14] Apache は CGIスクリプトの出力する日付の形式を (少なくても Last-Modified:
欄についてはチェックし、正しければその日付を、正しくなければ Unix epoch の日付を
RFC 1123 形式で出力します。この時、曜日が間違っていれば正しい値に直してくれます。
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 asGreenwich 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
HTTP/1.0HTTP/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 protocolsshouldSHOULD ensure that any Date header field present in a message conforms to one of theHTTP/1.0HTTP/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
などでは、依然、
非標準の日時形式が用いられることがあるようです。