PHPにおける時間表記のISO-8061、DATE_ATOM、DATE_RFC3309、DATE_W3Cの違いは何か
ISO-8601時刻表記について
ISO-8601はあまり使わない時刻を表記する形式ではあるがAtomフィードの時刻表記でその互換規格として利用されます。Atomについては最近記事を書いたのでそちらを参照してください。RSSより便利なAtomデータの詳細と利用方法について簡単にまとめてみた - Yuta.Kikuchiの日記 ISO-8601とは簡単に説明すると時刻の表記を以下のような形式で表現します。
- 年、月、日の関係はYYYY-MM-DDと表記する。(2012-01-24、20120124)。
- 年、年内の日番号はYYYY-DDDと表記する。(2012024) 2012年の24日目。
- 年、週、曜日をYYYY-Www-Dと表記する。(2012-W04-2) 2012年の4週目の火曜日。すなわち2012/01/24。
- 時刻の表記にはhh:mm:ssの形式が利用される。
- 10時30分20.5秒 ( 10:30:20,5 )
- 10:30,5(1130,5)は10:30:30と同じ。
- 10.5は10:30と同じ。
- timezone指定
- 日付と時刻の間にはTを入れる。2012-01-24T12:00+09:00
- 期間を表記する場合は開始日時/終了日で表記する。2012-01-01T00:00+09:00/2012-01-24T12:00+09:00 (2012/01/01の0時〜2012/01/24の12時)
年/月/日の表記が省略表記等自由に表現できることや期間の表現が可能であるというメリットはありますが、定義が曖昧なのと人の目には分かりづらい表記のように思います。(timestampよりはましですが)。しかしほとんどのプログラミング言語、ミドルウェアはこの表記をサポートしているということで覚えた方が良いという事です。
AtomのDateコンストラクタ
RFC 4287 The Atom Syndication Format 日本語訳 ここのDateコンストラクタ定義によるとRFC3339に準拠している必要があるようですが、この規格自体がISO-8601やW3C.NOTE-datetime-19980827、W3C.REC-xmlschema-2-20041028と互換性があります。以下はDateコンストラクタの簡単な例になります。
<updated>2012-01-24T00:00:00Z</updated> <updated>2012-01-24T00:00:00.00Z</updated> <updated>2012-01-24T00:00:00+09:00</updated> <updated>2012-01-24T00:00:00.00+09:00</updated>
PHPでの各規格の表記の違い
PHP: DateTime - Manual
ここに載っているDateTime Manualの表記の違いについてコメントしますが、結論からするとISO8601だけ少し表記が違うぐらいの差でしかありません。なぜなら上のISO-8601の定義から同じ時刻を示すからです。規格自体が変わらないのだとすれば定数を増やすのは無意味と感じてしまいます。
定数 実データ DATE_ISO8601 2012-01-23T23:14:15+0900 DATE_RFC3339 2012-01-23T23:14:15+09:00 DATE_ATOM 2012-01-23T23:14:15+09:00 DATE_W3C 2012-01-23T23:14:15+09:00 PHP: date - Manual
こちらのdate関数の説明も更に混乱を招きます。date関数の第一引数に'c'を指定するとISO8601形式と書いてありますが、実際には他の3パターンの時刻表記で表示されます。以下はPHPのサンプルコードとその実行結果です。どれも同じ値を示しますが混乱しないように注意しましょう。<? //timezone設定 date_default_timezone_set('Asia/Tokyo'); //ISO 8601 echo date( DATE_ISO8601, time() ) . "\n"; echo date( 'Y-m-d\TH:i:sO', time() ) . "\n"; //ATOM echo date( 'c', time() ) . "\n"; echo date( 'Y-m-d\TH:i:sP' ) . "\n"; echo date( DATE_ATOM, time() ) . "\n"; //RFC3339 echo date( 'Y-m-d\TH:i:sP' ) . "\n"; echo date( DATE_RFC3339, time() ) . "\n"; //W3C echo date( 'Y-m-d\TH:i:sP' ) . "\n"; echo date( DATE_W3C, time() ) . "\n";2012-01-24T00:00:00+0900 2012-01-24T00:00:00+0900 2012-01-24T00:00:00+09:00 2012-01-24T00:00:00+09:00 2012-01-24T00:00:00+09:00 2012-01-24T00:00:00+09:00 2012-01-24T00:00:00+09:00 2012-01-24T00:00:00+09:00 2012-01-24T00:00:00+09:00Pythonで表記するとどうなるか
折角なのでPythonでも上の時刻表期に挑戦してみます。ISO-8601とRFC3339を見てみます。
それぞれパース用のパッケージが作成されています。ISO-8601とRFC3339です。今回は標準モジュールのimportでISO-8601とrfc3339.pyを利用してRFC3339の時刻表記の作成を行いたいと思います。
- ISO-8601
#!/usr/bin/env python # -*- coding: utf-8 -*- from datetime import tzinfo, timedelta, datetime class TZ(tzinfo): def utcoffset(self, dt): return timedelta(minutes=+540) print datetime(2012, 01, 24, 00, 00 tzinfo=TZ()).isoformat()
- RFC3339
#!/usr/bin/env python # -*- coding: utf-8 -*- import rfc3339 as rfc3339 rfc3339.UTC_TZ=rfc3339.tzinfo(540,'Z') print rfc3339.now()