2019-07-16に更新

PHPでHTTP-date形式の時刻を生成する

中々触れる機会は無いと思いますが、HTTP汎用ヘッダーに使われる日付形式がやや特殊なためメモ。
最初のほうは仕様について書いています。コードが欲しい方は飛ばしてください。


仕様について

RFC7231では、HTTPレスポンスヘッダで日付と時刻を表現するための書式が決められています。

実際のレスポンスの例

Date: Sun, 14 Jul 2019 15:00:00 GMT
Expires: Tue, 13 Aug 2019 15:00:00 GMT
Last-Modified: Mon, 03 Oct 2016 15:12:06 GMT

この構文は「IMF-fixdate」と呼ばれ、次のように決められています。

<曜日>, <日> <月> <年> <時>:<分>:<秒> GMT

IMF-fixdateは「RFC1123-date」とも呼ばれていますが、RFC1123から派生した書式であり、RFC1123とは異なります

具体的には次のような違いがあります。

RFC1123の日付形式 の例

Sun, 8 Jul 2019 15:00:00 +0000

  • タイムゾーンは地方時を指定でき、GMTからの時差「+0900」形式で表します。
  • 曜日、月は大文字小文字を区別しません。
  • 曜日、秒は省略できます。
  • 曜日の「,」は省略できます。
  • 日は1桁か2桁で表します。
  • 連続した空白が許容されています。

RFC1123は全体的にゆるめな印象です。
対照的なのがIMF-fixdateです。IMF-fixdateは固定長での表現を重視したため、複数の制限があります。

HTTPの日付形式(IMF-fixdate) の例

Sun, 08 Jul 2019 15:00:00 GMT

  • タイムゾーンは必ず「GMT」と書きます。GMT以外の指定はできません
  • 曜日、月は大文字小文字を区別します
  • 曜日、秒、「,」いずれも必須です
  • 日は2桁でなければなりません
  • 空白はU+00201文字だけを入れなければなりません

本題

なぜRFC1123の話をしたのかと言うと、PHPのDateTimeクラスには書式の定義済み変数が用意されているのですが、その中の「DATE_RFC1123」の書式がHTTPの時間表現と異なるため、利用することができないからです。

とは言え、基本構文は同じですので、最後の「+0000」形式を「GMT」に戻せばいいことになります。

PHPでは、date()をグリニッジ標準時として利用できる gmdate() という関数があります。
これを利用すると、次のようなコードでHTTPの日付形式を表現できます。

gmdate('D, d M Y H:i:s T')

出力は完全なHTTPの日付形式となります。
gmdate()は第二引数にUnixタイムスタンプを指定することができます。

結論

header()とかで表記したいときはこのコードを使ってください。

補足になりますが、HTTPレスポンスヘッダでは歴史的理由によりIMF-fixdateの他にも2種類の書式を使うことができます。 RFC 850の日付形式 「rfc850-date」と、asctime形式「asctime-date」です。 しかしながら、これらは現在RFCで禁止されています。「ブラウザは必ず解釈できなければならない」とされているため全てのブラウザが解釈できますが、廃用形式とも言われていますし、使わないほうがいいでしょう。

引用・参考

Date - HTTP | MDN
https://developer.mozilla.org/ja/docs/Web/HTTP/Headers/Date

RFC 7231 — HTTP/1.1: Semantics and Content (日本語訳)
https://triple-underscore.github.io/RFC7231-ja.html#http.date

rfc1123-date - suikawiki
https://wiki.suikawiki.org/n/rfc1123-date

PHP: DateTime - Manual
https://www.php.net/manual/ja/class.datetime.php#datetime.constants.types

PHP: gmdate - Manual
https://www.php.net/manual/ja/function.gmdate.php

ツイッターでシェア
みんなに共有、忘れないようにメモ

ウラル

Splatoonの二次創作サイト「スプランプ」の管理人です。サーモンラン研究所やオクトチャット、フェス速報などを作りました。

Crieitは個人で開発中です。 興味がある方は是非記事の投稿をお願いします! どんな軽い内容でも嬉しいです。
なぜCrieitを作ろうと思ったか

また、「こんな記事が読みたいけど見つからない!」という方は是非記事投稿リクエストボードへ!

こじんまりと作業ログやメモ、進捗を書き残しておきたい方はボード機能をご利用ください!

ボードとは?

関連記事

コメント