php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #40743 DateTime ignores the TimeZone object passed to the constructor
Submitted: 2007-03-06 23:27 UTC Modified: 2013-01-06 16:13 UTC
Votes:10
Avg. Score:3.6 ± 1.5
Reproduced:6 of 7 (85.7%)
Same Version:1 (16.7%)
Same OS:0 (0.0%)
From: ddb at bitxtender dot de Assigned: derick
Status: Re-Opened Package: Date/time related
PHP Version: 5.2.1 OS: Win XP
Private report: No CVE-ID:
Have you experienced this issue?
Rate the importance of this bug to you:

 [2007-03-06 23:27 UTC] ddb at bitxtender dot de
Description:
------------
when you create a new DateTime object the timezone object you pass along in the constructor is ignored.
setting the timezone using setTimeZone works as expected.
also tested with 5.2-dev and 6.0-dev

Reproduce code:
---------------
$dt = new DateTime('@' . time(), new DateTimeZone('Europe/Berlin'));
echo $dt->format(DATE_RFC822);

Expected result:
----------------
Tue, 07 Mar 07 01:22:55 +0100

Actual result:
--------------
Tue, 07 Mar 07 00:22:55 +0000

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2007-04-11 14:45 UTC] derick@php.net
It's not totally ignored, but something fishy is going on. See the following script + output:

<?php
$dt = new DateTime();
echo $dt->format(DATE_RFC822 . " e T O"), "\n";

$dt = new DateTime('@' . time());
echo $dt->format(DATE_RFC822 . " e T O"), "\n";

$dt = new DateTime('@' . time(), new DateTimeZone('Europe/Berlin'));
echo $dt->format(DATE_RFC822 . " e T O"), "\n";
?>

Wed, 11 Apr 07 16:42:40 +0200 Europe/Oslo CEST +0200
Wed, 11 Apr 07 14:42:40 +0100 Europe/Oslo GMT+0100 +0100
Wed, 11 Apr 07 14:42:40 +0100 Europe/Berlin GMT+0100 +0100

 [2007-04-19 20:53 UTC] artur at jedlinski dot pl
It is ignoring the #2 parameter when you put the timezone info inside the #1. It's *absolutely* unacceptable.

// Europe/Warsaw = GMT +0200
$dateSrc = '2007-04-19 12:50:00 GMT';
$dateTime = new DateTime($dateSrc, new DateTimeZone('Europe/Warsaw'));
echo $dateTime->format('H:i:s')."<br />";
// RESULT: 12:50:00 (expected: 14:50:00)

$dateTime->setTimeZone(new DateTimeZone('Europe/Warsaw'));
echo $dateTime->format('H:i:s')."<br />";
// RESULT: 14:50:00 (correct)

IMHO the most intuitive way is to create the date based on the #1, but displays it using #2.

It's not only strange it ignores #2, but in fact it's strange that the internal DateTime pointer is set to timezone provided in #1 at all. If the date_default_timezone_set() was set to some TZ, it should create dates within this timezone if one doesn't state otherwise (using #2). Of course the timezone info from #1 should be used, but only to calculate the actual timestamp.

date_default_timezone_set('Europe/Warsaw');
$dateSrc = '2007-04-19 12:50:00 GMT';
$dateTime = new DateTime($dateSrc);
echo $dateTime->format('H:i:s')."<br />";
// RESULT: 12:50:00 (expected: 14:50:00)

Currently, it's pretty complicated to translate dates from one timezone to another - you have to use DateTime::setTimeZone(), when one line should do the thing:

$dateTime = new DateTime($dateWithSrcTimeZone, $timeZoneToDisplay);
(or even without $timeZoneToDisplay if you want to use your current TZ).
 [2008-01-17 18:50 UTC] derick@php.net
This bug has been fixed in CVS.

Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.
 
Thank you for the report, and for helping us make PHP better.


 [2012-02-09 02:28 UTC] kavi at postpro dot net
This bug is NOT fixed on 5.3.3 or trunk.

$ php

<?php

$a = new DateTime('Monday, 15-Aug-05 15:52:01 PDT', new 
DateTimeZone('America/New_York'));
print_r($a);


DateTime Object
(
    [date] => 2005-08-15 15:52:01
    [timezone_type] => 2
    [timezone] => PDT
)
 [2012-05-17 19:29 UTC] cataphract@php.net
Still present in master.

<?php
$dt = new DateTime('@' . time(), new DateTimeZone('Europe/Berlin'));
var_dump($dt, $dt->getTimeZone()->getName());

object(DateTime)#1 (3) {
  ["date"]=>
  string(19) "2012-05-17 19:29:15"
  ["timezone_type"]=>
  int(1)
  ["timezone"]=>
  string(6) "+00:00"
}
string(6) "+00:00"
 [2012-05-17 19:29 UTC] cataphract@php.net
-Status: Closed +Status: Re-Opened
 [2013-01-06 16:13 UTC] derick@php.net
-Type: Bug +Type: Feature/Change Request
 [2013-01-06 16:13 UTC] derick@php.net
It's still not a bug, so changing it to a feature request. The "@" acts as a timezone specifier and if there is one of those in the string to parse, then a passed in timezone doesn't override this. This works the same as:

$a = new DateTime("2013-01-06 16:12 CEST", new DateTimeZone("Asia/Tokyo"));
var_dump( $a );

which shows:

class DateTime#1 (3) {
  public $date =>
  string(19) "2013-01-06 16:12:00"
  public $timezone_type =>
  int(2)
  public $timezone =>
  string(4) "CEST"
}
 [2013-01-07 18:52 UTC] kavi at postpro dot net
Yes, it's a feature request for PHP to not soldier on without objection in a situation that is quite likely to be involved in a logic error.  This should be an E_WARNING at minimum.
 [2016-05-23 06:32 UTC] heiglandreas@php.net
IMHO there should be a difference in handling the timezone-information in the $time-parameter and the $timezone-parameter.

Regard this snippet: 

$date = new DateTime('2016-10-30 02:30:00+02:00', new DateTimeZone('Europe/Berlin'))
$date = new DateTime('2016-10-30 02:30:00+01:00', new DateTimeZone('Europe/Berlin'))

They ignore the $timezone-parameter even though that's the important thing IN THIS SPECIAL CASE as it's the double hour during falling back from DST to default offset. In this case the $timezone-parameter should be used to know that we're talking about one and the same timezone but different hours. The other way would be to use the (at least in germany used) notation of '20016-10-30 02A:30:00' or '20016-10-30 02B:30:00' for the first and the second occurence of the hour between 02:00H and 03:00H.
 
PHP Copyright © 2001-2016 The PHP Group
All rights reserved.
Last updated: Thu Aug 25 23:01:46 2016 UTC