ZF-8703: Zend_Date misses 3 days of a new year starting from 2010

Description

A colleague of me pointed out that Zend Date missed the first 3 days of 2010 by saying it was still 2009. Today, on January 4, 2010 it recovered itself and returned the correct year.

So, a quick test showed me this was indeed the case. I tested it first on Zend Framework 1.5.3 where the application was written for, but then retested my unit test for Zend Framework 1.6.9 with the same results.

My PHPUnit code: -- snip -- <?php

require_once 'PHPUnit/Framework.php'; require_once '../Zend/Date.php'; require_once '../Zend/Registry.php'; date_default_timezone_set('Europe/Brussels'); class Zend_DateTest extends PHPUnit_Framework_Testcase { protected $_locale;

 protected function setUp()
 {
     parent::setUp();
     $this->_locale = new Zend_Locale('en_US');
 }
 protected function tearDown()
 {
     $this->_locale = null;
     parent::tearDown();
 }
 public function testZendDateTranslatesDate31December2009Correctly()
 {
     $date = new Zend_Date('2009-12-31 07:00:00', 'YYYY-MM-dd HH:mm:ss', $this->_locale);
     $this->assertEquals('2009', $date->get(Zend_Date::YEAR_8601));
     $this->assertEquals('Dec 31, 2009', $date->get(Zend_Date::DATE_MEDIUM));
 }
 public function testZendDateTranslatesDateNewYearsDay2010Correctly()
 {
     $date = new Zend_Date('2010-01-01 07:00:00', 'YYYY-MM-dd HH:mm:ss', $this->_locale);
     $this->assertEquals('2010', $date->get(Zend_Date::YEAR_8601));
     $this->assertEquals('Jan 1, 2010', $date->get(Zend_Date::DATE_MEDIUM));
 }
 public function testZendDateTranslatesDate2January2010Correctly()
 {
     $date = new Zend_Date('2010-01-02 07:00:00', 'YYYY-MM-dd HH:mm:ss', $this->_locale);
     $this->assertEquals('2010', $date->get(Zend_Date::YEAR_8601));
     $this->assertEquals('Jan 2, 2010', $date->get(Zend_Date::DATE_MEDIUM));
 }
 public function testZendDateTranslatesDate3January2010Correctly()
 {
     $date = new Zend_Date('2010-01-03 07:00:00', 'YYYY-MM-dd HH:mm:ss', $this->_locale);
     $this->assertEquals('2010', $date->get(Zend_Date::YEAR_8601));
     $this->assertEquals('Jan 3, 2010', $date->get(Zend_Date::DATE_MEDIUM));
 }
 public function testZendDateTranslatesDate4January2010Correctly()
 {
     $date = new Zend_Date('2010-01-04 07:00:00', 'YYYY-MM-dd HH:mm:ss', $this->_locale);
     $this->assertEquals('2010', $date->get(Zend_Date::YEAR_8601));
     $this->assertEquals('Jan 4, 2010', $date->get(Zend_Date::DATE_MEDIUM));
 }

} -- snip --

Test results on Zend Framework 1.6.9: -- snip -- /usr/local/zend/bin/phpunit DateTest Zend/DateTest.php PHPUnit 3.4.3 by Sebastian Bergmann.

.FFF.

Time: 0 seconds

There were 3 failures:

1) Zend_DateTest::testZendDateTranslatesDateNewYearsDay2010Correctly Failed asserting that two strings are equal. --- Expected +++ Actual @@ @@ -2010 +2009

/Users/dragonbe/workspace/tests/zenddate/tests/Zend/DateTest.php:30

2) Zend_DateTest::testZendDateTranslatesDate2January2010Correctly Failed asserting that two strings are equal. --- Expected +++ Actual @@ @@ -2010 +2009

/Users/dragonbe/workspace/tests/zenddate/tests/Zend/DateTest.php:36

3) Zend_DateTest::testZendDateTranslatesDate3January2010Correctly Failed asserting that two strings are equal. --- Expected +++ Actual @@ @@ -2010 +2009

/Users/dragonbe/workspace/tests/zenddate/tests/Zend/DateTest.php:42

FAILURES! Tests: 5, Assertions: 7, Failures: 3.

Comments

It's correct behavior use "y" not "Y", read: http://framework.zend.com/issues/browse/ZF-5297

If you had googled only a tiny bit, you'd have found what you were doing wrong. It is also explicitly mentioned in the FAQ and reference guide.

I mentioned Zend Framework 1.6.9 which should be Zend Framework 1.9.6. My appologies.

It would be a lot less confusing if ZF would stick to what people are used to in plain old php.

date("Y") and date("y") do not represent different dates, but different formatting (4 vs 2 characters). People used to doing date("Y") and moving to Zend_Date and using YYYY there, will run into this problem. Ok, it's listed in the docs, but when you encounter this it seems like such an obvious bug that you don't think 'maybe it's intended behaviour'.

euhm, ok let me pull up my first tests then, which used lower case yyyy, but provided me the same faulty output. So, either my declaration of Zend Date should be written differently (please advice) or either this is still an issue.

My first PHPUnit code snip: -- snip -- <?php

require_once 'PHPUnit/Framework.php'; require_once '../Zend/Date.php'; require_once '../Zend/Registry.php'; date_default_timezone_set('Europe/Brussels'); class Zend_DateTest extends PHPUnit_Framework_Testcase { protected $_locale;

 protected function setUp()
 {
     parent::setUp();
     $this->_locale = new Zend_Locale('en_US');
 }
 protected function tearDown()
 {
     $this->_locale = null;
     parent::tearDown();
 }
 public function testZendDateTranslatesDate31December2009Correctly()
 {
     $date = new Zend_Date('2009-12-31 07:00:00', 'yyyy-MM-dd HH:mm:ss', $this->_locale);
     $this->assertEquals('2009', $date->get(Zend_Date::YEAR_8601));
     $this->assertEquals('Dec 31, 2009', $date->get(Zend_Date::DATE_MEDIUM));
 }
 public function testZendDateTranslatesDateNewYearsDay2010Correctly()
 {
     $date = new Zend_Date('2010-01-01 07:00:00', 'yyyy-MM-dd HH:mm:ss', $this->_locale);
     $this->assertEquals('2010', $date->get(Zend_Date::YEAR_8601));
     $this->assertEquals('Jan 1, 2010', $date->get(Zend_Date::DATE_MEDIUM));
 }
 public function testZendDateTranslatesDate2January2010Correctly()
 {
     $date = new Zend_Date('2010-01-02 07:00:00', 'yyyy-MM-dd HH:mm:ss', $this->_locale);
     $this->assertEquals('2010', $date->get(Zend_Date::YEAR_8601));
     $this->assertEquals('Jan 2, 2010', $date->get(Zend_Date::DATE_MEDIUM));
 }
 public function testZendDateTranslatesDate3January2010Correctly()
 {
     $date = new Zend_Date('2010-01-03 07:00:00', 'yyyy-MM-dd HH:mm:ss', $this->_locale);
     $this->assertEquals('2010', $date->get(Zend_Date::YEAR_8601));
     $this->assertEquals('Jan 3, 2010', $date->get(Zend_Date::DATE_MEDIUM));
 }
 public function testZendDateTranslatesDate4January2010Correctly()
 {
     $date = new Zend_Date('2010-01-04 07:00:00', 'yyyy-MM-dd HH:mm:ss', $this->_locale);
     $this->assertEquals('2010', $date->get(Zend_Date::YEAR_8601));
     $this->assertEquals('Jan 4, 2010', $date->get(Zend_Date::DATE_MEDIUM));
 }

}

Still produces the following failing test results: /usr/local/zend/bin/phpunit DateTest Zend/DateTest.php PHPUnit 3.4.3 by Sebastian Bergmann.

.FFF.

Time: 0 seconds

There were 3 failures:

1) Zend_DateTest::testZendDateTranslatesDateNewYearsDay2010Correctly Failed asserting that two strings are equal. --- Expected +++ Actual @@ @@ -2010 +2009

/Users/dragonbe/workspace/tests/zenddate/tests/Zend/DateTest.php:30

2) Zend_DateTest::testZendDateTranslatesDate2January2010Correctly Failed asserting that two strings are equal. --- Expected +++ Actual @@ @@ -2010 +2009

/Users/dragonbe/workspace/tests/zenddate/tests/Zend/DateTest.php:36

3) Zend_DateTest::testZendDateTranslatesDate3January2010Correctly Failed asserting that two strings are equal. --- Expected +++ Actual @@ @@ -2010 +2009

/Users/dragonbe/workspace/tests/zenddate/tests/Zend/DateTest.php:42

FAILURES! Tests: 5, Assertions: 7, Failures: 3.

Maybe you're right if we 'd done that from the start (though I believe there's logical reasoning behind the way it's been done now). However, suppose we'd change it now, my guess would be that we'd break a lot of applications. Besides that, it isn't that hard to read the manual / FAQ when using it, let alone googling it before reporting it as bug?

Reopening so that Thomas can at least have a look at it.

Actually the documentation is incomplete. The documentation claims:

"Year according to ISO 8601, at least four digit"

This is wrong, even ISO 8601 mentions a 'calendar year' which is 2009 for january 1, 2009. ISO 8601 has an alternative 'week number based year' which is less commonly used and which is 2008 for january 1, 2009. I think it's a mistake in both Zend_Date and the manual, to assume the less commonly used 'iso 8601 weeknumber based year' instead of the 'ISO 8601 calendrial year'.

Please dont close issues on my components without reproducing given code. This prevents irritations and us from reopening issues.

Changing priority

The described issue is documented and implemented this way since more than 3 years therefor critical is not correct.

I think it's really urgent. 2009 is the first year with 53 weeks. So the first year when its occuring.

Closing as duplicate of ZF-5297