Zend_Date のget()メソッドを使って、独自形式で日付文字列を取得したい場合に、
日付出力に関する定数を使って取得することも多いと思います。
例えば、’YYYY-MM-dd’ という指定で、年月日のハイフン区切り文字列を期待できますが、
‘YYYY-MM-dd’ ではなく、 ‘yyyy-MM-dd’ とした方が無難です。
Zend_Date Y指定子とy指定子 の説明
Zend_Dateのマニュアルに、’Y’と’y’に関する、気になる説明があります。
「年」 については、間違えやすい指定子がふたつあります。 ISO 形式の年を表す Y 指定子と、 実際の年を表す y 指定子です。 両者の違いは些細なものではありますが、非常に重要です。 Y は ISO 形式の年を算出するものです。 これは、カレンダーを作成する際によく用いられます。 2007 年 12 月 31 日を例にとって考えてみましょう。 実際の年は 2007 ですが、この日は 2008 年の最初の週 (第 1 週) の最初の日でもあります。 したがって、’dd.MM.yyyy’ として場合は ’31.December.2007′ が得られますが、’dd.MM.YYYY’ とした場合の結果は ’31.December.2008′ となるのです。これはバグではなく、期待通りの振る舞いです。 これが、ふたつの指定子の違いとなります。
日付関数全般用の定数 – Zend_Date – Zend Framework
オブジェクトの保持する日付の週番号が、実際の年の翌年に属する場合、‘Y’によって得られる年は翌年になってしまうということです。
これを知らずに’Y’を使うと結構ハマることがあります。
Zend_Date の挙動を確認
下記のコードで、実際に挙動を確認してみます。
テストコード(testZendDate.php)
<?php require_once('/usr/share/php/Zend/Date.php'); // 2012-12-30 を、YYYY形式とyyyy形式で表示 $date = new Zend_Date(strtotime('2012-12-30'), Zend_Date::TIMESTAMP); echo '2012-12-30 to YYYY-MM-dd='.$date->get('YYYY-MM-dd')."\n"; echo '2012-12-30 to yyyy-MM-dd='.$date->get('yyyy-MM-dd')."\n"; // 2012-12-31 を、YYYY形式とyyyy形式で表示 $date = new Zend_Date(strtotime('2012-12-31'), Zend_Date::TIMESTAMP); echo '2012-12-31 to YYYY-MM-dd='.$date->get('YYYY-MM-dd')."\n"; echo '2012-12-31 to yyyy-MM-dd='.$date->get('yyyy-MM-dd')."\n"; echo "\n"; // 2013-01-31 を、YYYY形式とyyyy形式で表示 $date = new Zend_Date(strtotime('2013-01-31'), Zend_Date::TIMESTAMP); echo '2013-01-31 to YYYY-MM-dd='.$date->get('YYYY-MM-dd')."\n"; echo '2013-01-31 to yyyy-MM-dd='.$date->get('yyyy-MM-dd')."\n"; // 2013-01-31 の1か月前 →2012-12-31のはず $date->add(-1, Zend_Date::MONTH); echo '2013-01-31 - 1month to YYYY-MM-dd='.$date->get('YYYY-MM-dd')."\n"; echo '2013-01-31 - 1month to yyyy-MM-dd='.$date->get('yyyy-MM-dd')."\n"; // end of file
テストコードの実行
[user@localhost]$ php testZendDate.php 2012-12-30 to YYYY-MM-dd=2012-12-30 2012-12-30 to yyyy-MM-dd=2012-12-30 2012-12-31 to YYYY-MM-dd=2013-12-31 2012-12-31 to yyyy-MM-dd=2012-12-31 2013-01-31 to YYYY-MM-dd=2013-01-31 2013-01-31 to yyyy-MM-dd=2013-01-31 2013-01-31 - 1month to YYYY-MM-dd=2013-12-31 2013-01-31 - 1month to yyyy-MM-dd=2012-12-31 [user@localhost]$
ここで問題になるのは、2012-12-31 です。
2012-12-31は、2013年1月の第1週目ということになるため、
‘YYYY’を使用すると、[2013]が得られます。
実際にこのように文字列として年月日を渡している場合には、
比較的すぐに異常に気付くと思うのですが、
Zend_Dateを使って月の加減算を行っている場合、
特定のタイミングでしか問題が発生しないため、原因調査が少し面倒になります。
上記の例だと、2013-01-31の1か月前を期待しても、2013-12-31になってしまいます。
まとめ
Zend_Dateの日付文字列を取得したい場合は、年の指定には’y’を使うのが無難です。
といっても、’Y’の存在意義が無いわけではなくて、用途としては、
Zend_Dateのマニュアルの説明にもある通り、カレンダー表示などの特定の用途や、
週番号を取得した際に、その週番号が該当する年度を知りたい場合、とかでしょうか。
他にも ‘Y’ には大きな意味があるのかもしれませんが、
単純に年月日を取得したいというだけなら、とにかく’y’を使っておけば間違いは無いでしょう。
最近のコメント