ZF-6199: Incorrect disambiguation of format in Zend_Date

Description

There appears to be a problem with date disambiguation on formats which should not be ambiguous. Dates in the form YYYY-MM-DD should, I believe, never be misinterpreted as YYYY-DD-MM. (This is only a problem in DD/MM/YYYY vs MM/DD/YYYY). Amazon returns their dates in this format, as does eBay - and likely many other web services.

Example, using a date as might be returned from eBay in ISO 8601 format:

$date = new Zend_Date('2009-04-03T0:00:00.000Z'); echo $date;

Expected (anywhere in the world): Apr 3, 2009 12:00:00 AM

Actual: Mar 4, 2009 12:00:00 AM

I can work around this by calling it as

new Zend_Date('2009-04-03T0:00:00.000Z', 'en_AU')

However, I shouldn't have to, and this is still going to cause problems for people in locales which use the US format.

Slightly related to this issue is the fact that the Z on the end of the date is a timezone indicator for GMT. Perhaps this should override the currently set timezone for the date object, or at least be documented that it is ignored and the timezone needs to be set to GMT manually (I didn't check if differential offsets are handled or not).

Comments

The fact is that you are not giving ANY constant when you create Zend_Date. This means that Zend_Date expects that you use localized input.

The date format is in that case used from your locale which is eighter defined by your browser or your server. When you give a FIXED input, then you have also to set the proper date constant, otherwise the date will not be recognised correctly.

This is not a problem of Zend_Date, as it can not know if you want to use RFC2822 or RFC850.

As you have not given the complete output of your instance of Zend_Date we can not reproduce the timezone behaviour. Z is supported and also recognised. But as before this depends on the used constant.

Thank you. That makes sense.

I'm not sure what the server's default locale is, although if anything I would expect the Australian format to cause a problem. Given that providing a constant is pretty much mandatory, I wonder if throwing an exception might be a better option? I spent ages reading and trying to understand the manual and still didn't realize I needed the constant. It might save a lot of USER=ID10T errors.

I fixed the test code with a Zend_Date::ISO_8601 though it still seems to ignore Z. This is the pertinent code:

date_default_timezone_set('Australia/Brisbane'); $test = new Zend_Date('2009-04-15T09:22:17.000Z', Zend_Date::ISO_8601); echo $test->getTimezone() . ' ' . $test . "\n";

I get:

Australia/Brisbane Apr 15, 2009 9:22:17 AM

expected:

Australia/Brisbane Apr 15, 2009 7:22:17 PM

The dump of the Zend_date instance looks like this:

object(Zend_Date)#2 (8) { ["_locale:private"]=> string(2) "en" ["_fractional:private"]=> int(0) ["_precision:private"]=> int(3) ["_unixTimestamp:private"]=> string(10) "1239751337" ["_timezone:private"]=> string(18) "Australia/Brisbane" ["_offset:private"]=> int(-36000) ["_syncronised:private"]=> int(0) ["_dst:protected"]=> bool(true) }

Fixed