hnwの日記

PHPの日付文字列の解釈ルールがドキュメント化されました

PHPのstrtotime関数やDateTimeクラスは、様々なフォーマットの日付文字列を解釈し、時刻として取り扱うことができます。たとえば次のような文字列を解釈することができます。

  • "Wednesday July 23rd, 2008"(=2008年7月23日)
  • "first Wednesday July 23rd, 2008"(=2008年7月30日、PHP5.1.0以降)
  • "first Wednesday of July 23rd, 2008"(=2008年7月2日、PHP5.3.0以降)


こうした日付の解釈はPHP独自の実装です*1。当初はGNUの日付記法に準拠していたようですが*2、今や別物といっていいでしょう。にもかかわらず、これまで解釈ルールの詳細を説明するドキュメントが存在しない状態が続いていました。


そのため、仕様を推測する根拠はstrtotime関数のサンプルコードとPHPソースコードのテストケースくらいしかありませんでした。ごく最近まで機能追加やバグ修正が入っていたこともあり、ソースコードから読み取った挙動さえ仕様とは言えない状態だったのです。実際、PHP5.2.7から'+1 Monday'の解釈結果が変わったのはバグではないかというバグレポートを出したことがあるのですが、今までの挙動がバグでPHP5.2.7から修正されたんだと言われてしまいました(PHP Bugs: #43452)。


この解釈ルールについての文書が、2010年3月頃になってようやくPHPマニュアルに追加されました(英語版:「Supported Date and Time Formats」)。これを受けて、PHPマニュアルの和訳について議論しているPHP-doc ML上で、僕がこの和訳に立候補しまして、2010年の11月末あたりからこの和訳も公開されています(和訳:「サポートされている日付と時刻の書式」)。


仕様が文書化されていれば、少なくとも仕様として書いてあることは未来にわたって変わりにくいと期待できますから、利用する上での基準にもなります。このブログでもstrtotime関数の仕様の曖昧さについて「strtotime関数との付き合い方」という記事で注意喚起したことがありました。当時は、かなり限定的な書式のみ使うのが安全だろうと紹介しましたが、今回この解釈ルールが公開されたことで、安心して使える範囲が広がったと言えるでしょう。


本稿では、この解釈ルールの中で注目すべき点について3点紹介します。

*1:PHP 5.3.5現在、解釈のコア部分はre2cで書かれています。興味を持った方はext/date/lib/parse_date.reを眺めてみてください。

*2:過去のstrtotimeのマニュアルにはそのような記述があり、「Date Input Formats」へリンクされていました。

続きを読む