Smile Engineering Blog

ジェイエスピーからTipsや技術特集、プロジェクト物語を発信します

Date ヘッダ

はじめに

テストなんかで急に Date ヘッダ を用意しなきゃダメな場面はよくあると思います。今までは Epoch Converter からコピーペなどして使っていたんですが、ローカルで求める方法があったのでご紹介します。

date コマンド

いきなり答えですが、date コマンドの -R オプションを使用します。

実行例:

$ TZ=Etc/GMT date -R | sed 's/+0000$/GMT/'
Sat, 24 Jul 2021 01:02:34 GMT

-R オプションは RFC 5322 フォーマットで出力するオプションです。

date コマンドのマニュアルより:

-R, --rfc-email
  output date and time in RFC 5322 format.  Example: Mon, 14 Aug 2006 02:34:56 -0600

ただ、RFC 5322 フォーマットでは Date ヘッダの仕様にはいまひとつ及びません。タイムゾーンがローカル、かつ 4 ケタの数値フォーマットになっています。Date ヘッダの方は

HTTP の日付は常に GMT で表され、決して現地時間で表されることはありません。

とあるように、常に GMT(+0000)で表示されなければなりません。そのため、

  1. シェル変数 TZタイムゾーンGMT に設定し、
  2. date -R コマンドで表示された結果を sed コマンドにパイプし、GMT を表す "+0000" を探して "GMT" に置換する

という方法で実現しています。

Python

ちなみに Python では、formatdate が使えます。

実行例:

Python 3.9.5 (default, May 11 2021, 08:20:37) 
[GCC 10.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from email.utils import formatdate
>>> formatdate(usegmt=True)
'Sat, 24 Jul 2021 12:43:46 GMT'

こちらもドキュメントには RFC 2822 形式の文字列で返す、とあります。オプション引数 usegmt に True をセットすることにより、Date ヘッダの仕様に沿うことができます。(オプション引数 localtime のデフォルトが False なので UTCGMT)が使われる)

さいごに

ちなみに UNIX 時間(秒)を得たい場合は、

$ date +%s
1627118680

です。さらにミリ秒までを得たい場合は、

$ date +%s%3N
1627205080123

です。 %N が nanoseconds を得るオプション、その前の数値 3 は表示幅なので、上位 3 ケタ、つまりミリ秒を UNIX 時間(秒)に連結することにより実現しています。