ISO-8601-Stolperfalle bei Zend_Date

Jeder der mit Datumswerten gearbeitet hat, weiß (oder sollte zumindest) um die kleinen und großen Untiefen wie Zeitzonen, Zeitumstellung und Schaltjahre die es dabei zu umschiffen gilt. Neben der seit PHP 5.2 verfügbaren DateTime-Klasse gibt es im Zend Framework die ältere Zend_Date-Komponente. Mit beiden lässt sich die Handhabung von Datumswerten in einer Applikation vereinfachen und vereinheitlichen:

<?php
$date = new Zend_Date('01.01.2011', null, 'de_DE');
echo $date; // 01.01.2011 00:00:00

Soweit so gut. Formatieren kann man das Datum mit Zend_Date auch, zum Beispiel zur Verwendung in einem MySQL-Query:

<?php
$date = new Zend_Date('01.01.2011', null, 'de_DE');
echo $date->toString('yyyy-MM-dd HH:mm:ss'); // 2011-01-01 00:00:00

Bei der Verwendung der Formatcodes ist darauf zu achten “yyyy” und das ähnlich aussehende “YYYY” keinesfalls zu verwechseln! Beide geben zwar das Jahr aus, aber mit einem kleinen, aber gewichtigen Unterschied.

Intern verwendet Zend_Date zur Formatierung die date-Funktion und konvertiert die Zend_Date-Formatcodes entsprechend. Während “yyyy” zu “Y” konvertiert wird und das erwartete Ergebnis liefert, wird “YYYY” zu “o” umgewandelt. Und “o” hat folgende Bedeutung:

ISO-8601 year number. This has the same value as Y, except that if the ISO week number (W) belongs to the previous or next year, that year is used instead. (added in PHP 5.1.0)
php.net

Da die erste Tage im Jahr 2011 noch zur letzten Kalenderwoche des Jahres 2010 gehören, wird gemäß ISO 8601 das Jahr 2010 ausgegeben. Und das dürfte in den seltesten Fällen das sein, was man möchte…