Zend Framework

Zend_Date_DateObject::date returns timestamp with added timezone offset when timestamp is outside the range of what PHP's date() can handle

Details

  • Type: Bug Bug
  • Status: Resolved Resolved
  • Priority: Major Major
  • Resolution: Not an Issue
  • Affects Version/s: 1.9.2
  • Fix Version/s: 1.10.0
  • Component/s: Zend_Date
  • Labels:
    None

Description

Getting the timestamp of a Zend_Date object returns a wrong timestamp if the timestamp is outside the range of what PHP's date() function can handle. That is roughly years 1901 to 2038 on my system. In the method Zend_Date_DateObject::date the timestamp is added with the current timezone offset if the year is outside the range 1901 - 2038. As I have understood it the timestamp is not timezone-dependant and should therefore always be relative to the GMT timezone. In other words the timestamp should stay the same regardless of what timezone you are in. I'm in the timezone "Europe/Helsinki" or "EET" with a timezone offset of 7200 seconds. This offset is always wrongly added to the timestamp if it is outside the 1901 - 2038 range, but stays as it is if inside that range.

Code to proove the bug:
<?php
date_default_timezone_set('EET');
//December 6th 1917 10:10:10
$timeArr = array('day' => 6, 'month' => 12, 'year' => 1917, 'hour' => 10, 'minute' => 10, 'second' => 10);
$dateObj = new Zend_Date($timeArr);
var_dump($dateObj); //shows that the private _unixTimestamp has a value of -1643212190
echo $dateObj->get(Zend_Date::TIMESTAMP); //returns -1643212190 which is correct

//December 6th 1817 10:10:10
$timeArr = array('day' => 6, 'month' => 12, 'year' => 1817, 'hour' => 10, 'minute' => 10, 'second' => 10);
$dateObj = new Zend_Date($timeArr);
var_dump($dateObj); //shows that the private _unixTimestamp has a value of -4798885790
echo $dateObj->get(Zend_Date::TIMESTAMP); //returns -4798878590 which is incorrect

//December 6th 2041 10:10:10
$timeArr = array('day' => 6, 'month' => 12, 'year' => 2041, 'hour' => 10, 'minute' => 10, 'second' => 10);
$dateObj = new Zend_Date($timeArr);
var_dump($dateObj); //shows that the private _unixTimestamp has a value of 2269930210
echo $dateObj->get(Zend_Date::TIMESTAMP); //returns 2269937410 which is incorrect
?>

Issue Links

Activity

Hide
Thomas Weidner added a comment -

You should have checked yourself your assumption. Then you would have seen that it's incorrect.
Run the following example code:

date_default_timezone_set('EET');
var_dump(mktime(0,0,0,10,10,2008));
$date = new Zend_Date('10.10.2008 00:00:00 EET');
var_dump($date->getTimestamp());

date_default_timezone_set('GMT');
var_dump(mktime(0,0,0,10,10,2008));
$date = new Zend_Date('10.10.2008 00:00:00 GMT');
var_dump($date->getTimestamp());

The returned content is:

int 1223586000
string '1223586000' (length=10)
int 1223596800
string '1223596800' (length=10)

As you can see the timestamp IS dependent from the timezone. When you think a little bit then the reason is quite logically.

When you set a date within timezone 1 then within timezone 2 the ACTUAL date is not the same... it differs by the timezone at the same timestamp.

At the timestamp where GMT has 02:00:00 within GMT+1 you have 03:00:00. By setting 02:00:00 within the timezone GMT+1 you have of course a difference of one hour which you are setting.

So the behaviour you have seen is correct.

Show
Thomas Weidner added a comment - You should have checked yourself your assumption. Then you would have seen that it's incorrect. Run the following example code:
date_default_timezone_set('EET');
var_dump(mktime(0,0,0,10,10,2008));
$date = new Zend_Date('10.10.2008 00:00:00 EET');
var_dump($date->getTimestamp());

date_default_timezone_set('GMT');
var_dump(mktime(0,0,0,10,10,2008));
$date = new Zend_Date('10.10.2008 00:00:00 GMT');
var_dump($date->getTimestamp());
The returned content is:
int 1223586000
string '1223586000' (length=10)
int 1223596800
string '1223596800' (length=10)
As you can see the timestamp IS dependent from the timezone. When you think a little bit then the reason is quite logically. When you set a date within timezone 1 then within timezone 2 the ACTUAL date is not the same... it differs by the timezone at the same timestamp. At the timestamp where GMT has 02:00:00 within GMT+1 you have 03:00:00. By setting 02:00:00 within the timezone GMT+1 you have of course a difference of one hour which you are setting. So the behaviour you have seen is correct.
Hide
Robin Lindroos added a comment -

Yes, everything is fine with dates inside the range of 1901 to 2038, so your example works fine as I new from my example. And Zend_Date::getTimestamp() always returns the correct timestamp. But if you call Zend_Date::get(Zend_Date::TIMESTAMP) then the value is incorrect. Let me give you another more simple example to demonstrate what goes wrong:

$timestamp = '-1643212190';
$dateObj = new Zend_Date($timestamp);
echo $timestamp . "\n";
echo $dateObj->getTimestamp() . "\n";
echo $dateObj->get(Zend_Date::TIMESTAMP) . "\n";

$timestamp = '-4798885790';
$dateObj = new Zend_Date($timestamp);
echo $timestamp . "\n";
echo $dateObj->getTimestamp() . "\n";
echo $dateObj->get(Zend_Date::TIMESTAMP);

This produces the output:

-1643212190
-1643212190
-1643212190
-4798885790
-4798885790
-4798878590

Why is the last unix timestamp not the same when calling get(Zend_Date::TIMESTAMP) and calling getTimestamp()?

Show
Robin Lindroos added a comment - Yes, everything is fine with dates inside the range of 1901 to 2038, so your example works fine as I new from my example. And Zend_Date::getTimestamp() always returns the correct timestamp. But if you call Zend_Date::get(Zend_Date::TIMESTAMP) then the value is incorrect. Let me give you another more simple example to demonstrate what goes wrong:
$timestamp = '-1643212190';
$dateObj = new Zend_Date($timestamp);
echo $timestamp . "\n";
echo $dateObj->getTimestamp() . "\n";
echo $dateObj->get(Zend_Date::TIMESTAMP) . "\n";

$timestamp = '-4798885790';
$dateObj = new Zend_Date($timestamp);
echo $timestamp . "\n";
echo $dateObj->getTimestamp() . "\n";
echo $dateObj->get(Zend_Date::TIMESTAMP);
This produces the output:
-1643212190
-1643212190
-1643212190
-4798885790
-4798885790
-4798878590
Why is the last unix timestamp not the same when calling get(Zend_Date::TIMESTAMP) and calling getTimestamp()?
Hide
Robin Lindroos added a comment -

The explanation Thomas Weidner gives here does not solve the issue I have. Of course the timestamp differs depending on the timezone when SETTING the date of a Zend_Date object from a date. But the timestamp should not be different in different timezones when GETTING the timestamp from the Zend_Date object.

Show
Robin Lindroos added a comment - The explanation Thomas Weidner gives here does not solve the issue I have. Of course the timestamp differs depending on the timezone when SETTING the date of a Zend_Date object from a date. But the timestamp should not be different in different timezones when GETTING the timestamp from the Zend_Date object.
Hide
Thomas Weidner added a comment -

You noted in your description:

As I have understood it the timestamp is not timezone-dependant and should therefore always be relative to the GMT timezone. In other words the timestamp should stay the same regardless of what timezone you are in.

This is a false assumption as you can see in the attached example. The timezone is always different for the same date when you are in another timezone.

Show
Thomas Weidner added a comment - You noted in your description:
As I have understood it the timestamp is not timezone-dependant and should therefore always be relative to the GMT timezone. In other words the timestamp should stay the same regardless of what timezone you are in.
This is a false assumption as you can see in the attached example. The timezone is always different for the same date when you are in another timezone.
Hide
Robin Lindroos added a comment -

Yes, I just meant that the timestamp is not and should not be timezode-dependant when getting the timezone from the date object. So just problem in communication

But great work with Zend_Date! It will be an invaluable part of our PHP project where it is necessary to handle dates as timestamps before the year 1901.

Show
Robin Lindroos added a comment - Yes, I just meant that the timestamp is not and should not be timezode-dependant when getting the timezone from the date object. So just problem in communication But great work with Zend_Date! It will be an invaluable part of our PHP project where it is necessary to handle dates as timestamps before the year 1901.

People

Vote (0)
Watch (1)

Dates

  • Created:
    Updated:
    Resolved: