何が起こったか?
CakePHP3にて、「(FrozenTime型)日付」から「年」を取得する処理に怪しい動作を発見しました。
use Cake\I18n\FrozenTime;
:
$time = new FrozenTime('2019-03-12');
echo $time->i18nFormat('YYYY-MM-dd')."\n"; # => 2019-03-12 が表示される
$time = new FrozenTime('2019-12-31');
echo $time->i18nFormat('YYYY-MM-dd')."\n"; # => 2020-12-31 が表示される!?
実際のコードでは年度を $time->i18nFormat('YYYY')
で取得しようとしていて、年末12/29~12/31あたりにおいて想定通りの年が取得できていませんでした。
CakePHP公式マニュアルでは?
日付を取得するには $time->i18nFormat('yyyy-MM-dd')
というふうに y を小文字にするのが正しそうです。
大文字 Y を使ったサンプルはみつかりません。
とはいえ $time->i18nFormat('YYYY-MM-dd')
でもそれっぽい値が取得できていますね。何が違うのでしょうか?
'y' と 'Y' の違い
"Uppercase Y is the year that the week of the timestamp in, in "Week of Year" based calendars. "
→ (大文字のYは、「Week of Year」ベースのカレンダーで、タイムスタンプの週が入った年です。)
2019年12月29日は、カレンダーで表示させると2020年の第1週でもあるため、大文字Yが2020を返したようです。
まとめ
CakePHP3のi18nFormat関数を使って日付を取得したいときは、$time->i18nFormat('YYYY-MM-dd')
ではなく $time->i18nFormat('yyyy-MM-dd')
を使いましょう!
確認環境
CakePHP 3.4.7
PHP 7.0.32