日付文字列のフォーマットのメモ
RFC 2822に従った日付文字列の生成
一発で出力できる指定子があることに気付かず、試行錯誤したのだが、せっかくなのでメモしておく。
RFC 2822に従った日付文字列は以下のような形式。
Thu, 18 Jun 2015 16:43:47 +0900
メールのヘッダなんかに使われることになっているもの。 ものによっては以下の形式も見かける。
Thu, 18 Jun 2015 16:43:47 +0900 (JST)
これをPHPで出力しようと思ったら、以下のように書けばいい。なお、PHPの初期設定をちゃんとやっていない環境なので余計な処理が冒頭に入っているが気にしない(謎)。
<?php date_default_timezone_set('Asia/Tokyo'); mb_internal_encoding('UTF-8'); $time = strtotime('2015-06-09 17:02:03'); printf("===date===\n"); printf(" %s\n", 'RFC 2822'); printf(" %s\n", date('r', $time)); printf(" %s\n", date('D, d M Y H:i:s O', $time)); printf(" %s\n", 'RFC 2822 with Timezone abbreviation'); printf(" %s\n", date('r (T)', $time)); printf(" %s\n", date('D, d M Y H:i:s O (T)', $time));
出力は以下のような感じ。
===date=== RFC 2822 Tue, 09 Jun 2015 17:02:03 +0900 Tue, 09 Jun 2015 17:02:03 +0900 RFC 2822 with Timezone abbreviation Tue, 09 Jun 2015 17:02:03 +0900 (JST) Tue, 09 Jun 2015 17:02:03 +0900 (JST)
ISO 8601拡張形式
ついでなのでやってみた(謎)。
ISO 8601拡張形式に従った日付文字列は以下のような形式。
2015-06-18T16:43:47+0900
これも、一発で出力できる指定子がある。
<?php date_default_timezone_set('Asia/Tokyo'); mb_internal_encoding('UTF-8'); $time = strtotime('2015-06-09 17:02:03'); printf("===date===\n"); printf(" %s\n", 'ISO 8601 date'); printf(" %s\n", date('c', $time)); printf(" %s\n", date('Y-m-d\TH:i:sP', $time));
出力。
===date=== ISO 8601 date 2015-06-09T17:02:03+09:00 2015-06-09T17:02:03+09:00
(ダメ)strftimeでRFC 2822形式
さらについでなので、strftime関数で色々やってみた。setLocale呼び出しに影響を受ける関数なので、当然ながら汎用性はないのだが‥
<?php date_default_timezone_set('Asia/Tokyo'); mb_internal_encoding('UTF-8'); $time = strtotime('2015-06-09 17:02:03'); printf("===strftime===\n"); $locales = array( '英語(US) ' => 'en_US', '英語(UK) ' => 'en_GB', '日本語 ' => 'ja_JP', 'ドイツ語 ' => 'de_DE', 'オランダ語 ' => 'nl_NL', 'フランス語(フランス)' => 'fr_FR', 'フランス語(カナダ) ' => 'fr_CA', 'スペイン語 ' => 'es_ES', 'ポルトガル語 ' => 'pt_PT', '中国語(繁体字) ' => 'zh_TW', '中国語(簡体字) ' => 'zh_CN', '韓国語 ' => 'ko_KR', ); $formats = array( 'RFC 2822' => '%a, %d %b %Y %H:%M:%S %z', 'RFC 2822 with Timezone abbreviation' => '%a, %d %b %Y %H:%M:%S %z (%Z)', ); foreach ($formats as $name => $format) { printf("%s\n", $name); foreach ($locales as $country => $locale) { printf(" %s(%s): ", setLocale(LC_ALL, $locale . '.UTF-8'), $country); printf(" %s\n", strftime($format, $time)); } }
出力。
===strftime=== RFC 2822 en_US.UTF-8(英語(US) ): Tue, 09 Jun 2015 17:02:03 +0900 en_GB.UTF-8(英語(UK) ): Tue, 09 Jun 2015 17:02:03 +0900 ja_JP.UTF-8(日本語 ): 火, 09 6月 2015 17:02:03 +0900 de_DE.UTF-8(ドイツ語 ): Di, 09 Jun 2015 17:02:03 +0900 nl_NL.UTF-8(オランダ語 ): di, 09 jun 2015 17:02:03 +0900 fr_FR.UTF-8(フランス語(フランス)): mar., 09 juin 2015 17:02:03 +0900 fr_CA.UTF-8(フランス語(カナダ) ): mar, 09 jun 2015 17:02:03 +0900 es_ES.UTF-8(スペイン語 ): mar, 09 jun 2015 17:02:03 +0900 pt_PT.UTF-8(ポルトガル語 ): Ter, 09 Jun 2015 17:02:03 +0900 zh_TW.UTF-8(中国語(繁体字) ): 二, 09 6月 2015 17:02:03 +0900 zh_CN.UTF-8(中国語(簡体字) ): 二, 09 6月 2015 17:02:03 +0900 ko_KR.UTF-8(韓国語 ): 화, 09 6월 2015 17:02:03 +0900 RFC 2822 with Timezone abbreviation en_US.UTF-8(英語(US) ): Tue, 09 Jun 2015 17:02:03 +0900 (JST) en_GB.UTF-8(英語(UK) ): Tue, 09 Jun 2015 17:02:03 +0900 (JST) ja_JP.UTF-8(日本語 ): 火, 09 6月 2015 17:02:03 +0900 (JST) de_DE.UTF-8(ドイツ語 ): Di, 09 Jun 2015 17:02:03 +0900 (JST) nl_NL.UTF-8(オランダ語 ): di, 09 jun 2015 17:02:03 +0900 (JST) fr_FR.UTF-8(フランス語(フランス)): mar., 09 juin 2015 17:02:03 +0900 (JST) fr_CA.UTF-8(フランス語(カナダ) ): mar, 09 jun 2015 17:02:03 +0900 (JST) es_ES.UTF-8(スペイン語 ): mar, 09 jun 2015 17:02:03 +0900 (JST) pt_PT.UTF-8(ポルトガル語 ): Ter, 09 Jun 2015 17:02:03 +0900 (JST) zh_TW.UTF-8(中国語(繁体字) ): 二, 09 6月 2015 17:02:03 +0900 (JST) zh_CN.UTF-8(中国語(簡体字) ): 二, 09 6月 2015 17:02:03 +0900 (JST) ko_KR.UTF-8(韓国語 ): 화, 09 6월 2015 17:02:03 +0900 (JST)
試した環境では「ja_JP.UTF-8」のようにしないと、マルチバイト文字がうまく見えなかったが、きっと環境のせい。
英語なんかだと、当然ながら期待する出力になっている。 ただし、期待する出力になっているlocaleでも、Windows環境など、環境によっては全然違う文字列が生成されることもあるので注意するようにということがマニュアルには書いてある。
(ダメ)strftimeでISO 8601拡張形式
さらにさらについでなので、strftime関数で色々やってみた。当然ながら(ry
<?php /* * http://php.net/manual/ja/function.strftime.php * http://php.net/manual/ja/function.date.php */ date_default_timezone_set('Asia/Tokyo'); mb_internal_encoding('UTF-8'); $time = strtotime('2015-06-09 17:02:03'); printf("===strftime===\n"); $locales = array( '英語(US) ' => 'en_US', '英語(UK) ' => 'en_GB', '日本語 ' => 'ja_JP', 'ドイツ語 ' => 'de_DE', 'オランダ語 ' => 'nl_NL', 'フランス語(フランス)' => 'fr_FR', 'フランス語(カナダ) ' => 'fr_CA', 'スペイン語 ' => 'es_ES', 'ポルトガル語 ' => 'pt_PT', '中国語(繁体字) ' => 'zh_TW', '中国語(簡体字) ' => 'zh_CN', '韓国語 ' => 'ko_KR', ); $formats = array( 'ISO 8601 date' => '%Y-%m-%dT%H:%M:%S%z', ); foreach ($formats as $name => $format) { printf("%s\n", $name); foreach ($locales as $country => $locale) { printf(" %s(%s): ", setLocale(LC_ALL, $locale . '.UTF-8'), $country); printf(" %s\n", strftime($format, $time)); } }
出力。
===strftime=== ISO 8601 date en_US.UTF-8(英語(US) ): 2015-06-09T17:02:03+0900 en_GB.UTF-8(英語(UK) ): 2015-06-09T17:02:03+0900 ja_JP.UTF-8(日本語 ): 2015-06-09T17:02:03+0900 de_DE.UTF-8(ドイツ語 ): 2015-06-09T17:02:03+0900 nl_NL.UTF-8(オランダ語 ): 2015-06-09T17:02:03+0900 fr_FR.UTF-8(フランス語(フランス)): 2015-06-09T17:02:03+0900 fr_CA.UTF-8(フランス語(カナダ) ): 2015-06-09T17:02:03+0900 es_ES.UTF-8(スペイン語 ): 2015-06-09T17:02:03+0900 pt_PT.UTF-8(ポルトガル語 ): 2015-06-09T17:02:03+0900 zh_TW.UTF-8(中国語(繁体字) ): 2015-06-09T17:02:03+0900 zh_CN.UTF-8(中国語(簡体字) ): 2015-06-09T17:02:03+0900 ko_KR.UTF-8(韓国語 ): 2015-06-09T17:02:03+0900
こっちは、localeに依存しない指定子しかつかっていないからか、localeに関係なく、試した範囲では同じ出力だった。 まぁ、変な心配をするより、素直にdate関数を使えという話だが‥