|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2012-05-05 20:45 UTC] php at arjanonline dot net
Description:
------------
When I create a DateTime object from a (any) timestamp and then add a DateInterval object to the DateTime object, the time in the DateInterval object is added and one additional hour is also added.
I have not noticed this behavior in versions up to and including 5.3.8, only in newer 5.3 versions. (I did not test in 5.4.)
Also the behavior is related to the default time zone, even though the created DateTime object is in UTC. I have tested several timezones and it appears that all Europe/* and North American America/* timezones are affected. The Australian timezones seem to be unaffected.
Information from phpinfo():
date
- date/time support => enabled
- "Olson" Timezone Database Version => 2012.3
- Timezone Database => internal
Test script:
---------------
date_default_timezone_set('Europe/Amsterdam');
$d1 = new DateTime('@0');
$d2 = clone($d1);
$d2->add(new DateInterval('PT5S'));
var_dump($d2);
Expected result:
----------------
object(DateTime)[2]
public 'date' => string '1970-01-01 00:00:05' (length=19)
public 'timezone_type' => int 1
public 'timezone' => string '+00:00' (length=6)
Actual result:
--------------
object(DateTime)[2]
public 'date' => string '1970-01-01 01:00:05' (length=19)
public 'timezone_type' => int 1
public 'timezone' => string '+00:00' (length=6)
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Mon Oct 27 16:00:01 2025 UTC |
My result is object(DateTime)#2 (3) { ["date"]=> string(19) "1970-01-01 00:00:05" ["timezone_type"]=> int(1) ["timezone"]=> string(6) "+00:00" } My system is MAC 10.6.8 php 5.3.1To amend my earlier comment: my repro attempts show that if I create an instance of DateTime by passing a string to the constructor, everything works fine. If I use a timestamp in combination with DateTime::createFromFormat, I see the bug affect the results Use of a string ------------------------- $start = new DateTime('09/13/2012 7:00pm'); $end = new DateTime('09/13/2012 8:00pm'); $interval = DateInterval::createFromDateString('30 minutes'); // expected, 1 hours, 0 minutes, get 1 hours, 0 minutes $diff = $start->diff($end); print 'Diff: '.$diff->h.' hours, '.$diff->i.' minutes'."\n"; $end->add($interval); $diff = $start->diff($end); // ecpected: 1 hours, 30 minutes, get 1 hours, 30 minutes print "\n".'Diff after interval: '.$diff->h.' hours, '.$diff->i.' minutes'; Use of a timestamp ------------------------- $start = DateTime::createFromFormat('U', 1347577200); $end = DateTime::createFromFormat('U', 1347580800); $interval = DateInterval::createFromDateString('30 minutes'); // expected, 1 hours, 0 minutes, get 1 hours, 0 minutes $diff = $start->diff($end); print 'Diff: '.$diff->h.' hours, '.$diff->i.' minutes'."\n"; $end->add($interval); $diff = $start->diff($end); // ecpected: 1 hours, 30 minutes, get 2 hours, 30 minutes print "\n".'Diff after interval: '.$diff->h.' hours, '.$diff->i.' minutes'; http://3v4l.org/fivbW The extra one hour makes less sense considering that my server timezone is -5 UTC -- not that it makes sense for DateInterval to be sensitive to timezone!This bug seems to be still present in PHP 5.3.19. My test script: <?php // The local system is set to Europe/Berlin timezone, so set it for PHP, too: date_default_timezone_set( 'Europe/Berlin'); echo 'Current date: ' . date('c') . PHP_EOL; // Now, we are switching to UTC... date_default_timezone_set( 'UTC'); $timezone = new DateTimeZone( 'UTC' ); $datetime = new DateTime( null, $timezone ); $datetime->setTime( 00, 00, 00 ); $datetime->add( new DateInterval( 'P1D' ) ); // Output echo 'mktime(): ' . ( mktime( 23, 59, 59 ) + 1 ) . PHP_EOL; echo 'gmmktime(): ' . ( gmmktime( 23, 59, 59 ) + 1 ) . PHP_EOL; echo 'datetime(): ' . $datetime->getTimestamp() . PHP_EOL; echo 'time(): ' . time() . PHP_EOL; echo 'microtime(): ' . microtime( true ) . PHP_EOL; echo 'Used TZ: ' . date_default_timezone_get() . PHP_EOL; ?> I run this test script at 2012-11-24T00:00:00+01:00. This is my output: Current date: 2012-11-24T00:00:00+01:00 mktime(): 1353715200 gmmktime(): 1353715200 datetime(): 1353715200 time(): 1353711600 microtime(): 1353711600.7557 Used TZ: UTC I am expecting that at least the DateTime value should be equal to time(), because both functions should represent a UNIX timestamp (which is per definition UTC). But I am also not sure if the gmmktime() *and* mktime() should be equal... and I don't understand the 3600 offset at all - remember, we set UTC timezone before...Similiar issue: The following code doesn't work with particular date 2015-02-21 23:45:00 when trying to add 15 minutes... $date1 = new DateTime('2015-02-21 23:45:00'); $interval = new DateInterval('PT15M'); print_r($date1); $date1->add($interval); print_r($date1); Output DateTime Object ( [date] => 2015-02-21 23:45:00.000000 [timezone_type] => 3 [timezone] => America/Sao_Paulo ) DateTime Object ( [date] => 2015-02-21 23:00:00.000000 [timezone_type] => 3 [timezone] => America/Sao_Paulo ) Expected Output DateTime Object ( [date] => 2015-02-22 00:00:00.000000 [timezone_type] => 3 [timezone] => America/Sao_Paulo )The original issue seems to be fixed in currently supported PHP-Versions. Therefore I'm closing this issue. PHP 7.1.2: php > date_default_timezone_set('Europe/Amsterdam'); php > $d1 = new DateTime('@0'); php > $d2 = clone($d1); php > $d2->add(new DateInterval('PT5S')); php > var_dump($d2); php shell code:1: class DateTime#5 (3) { public $date => string(26) "1970-01-01 00:00:05.000000" public $timezone_type => int(1) public $timezone => string(6) "+00:00" }