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
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関数を使えという話だが‥