2

This code:

$timestamp = 1423522800;  // Timestamp for 2015-02-10
$date1 = DateTime::createFromFormat('U', $timestamp);

echo $date1->format('d/m/Y H:i') . "\n";
echo $date1->format('U') . "\n\n";

$date2 = new DateTime('2015-02-10');

echo $date2->format('d/m/Y H:i') . "\n";
echo $date2->format('U') . "\n";

Gives me this output:

09/02/2015 23:00
1423522800

10/02/2015 00:00
1423522800

What the hell is going on?

I think it's timezone related, but from the DateTime::createFromFormat() documentation:

Note: The timezone parameter and the current timezone are ignored when the time parameter either contains a UNIX timestamp (e.g. 946684800) or specifies a timezone (e.g. 2010-01-28T15:00:00+02:00).

I'm using PHP 5.5.9-1ubuntu4.5

3
  • Yes, it's time-zone related. $date1 is created without any TZ assumptions, but once you start calling format(), you'll be implicitly applying TZ data, so your time-less date will get mangled into whatever DateTime is using for your TZ, as if the original date/time was UTC. Commented Feb 10, 2015 at 16:54
  • Did you set the default timezone ? date_default_timezone_set($tz);? I just ran it with $tz="America/Los_Angeles" and got 09/02/2015 23:00: 1423522800, 10/02/2015 00:00: 1423555200, respectively. Commented Feb 10, 2015 at 16:59
  • 1
    My default timezone is Europe/Madrid but if I change it to UTC with date_default_timezone_set('UTC') at the begining of the script the result is the same. Commented Feb 10, 2015 at 17:24

1 Answer 1

1

When a DateTime object from a UNIX timestamp with

$timestamp = 1423522800;  // Timestamp for 2015-02-10
$date1 = DateTime::createFromFormat('U', $timestamp);

or

$date1 = new DateTime('@'.$timestamp);

or

$date1 = date_create('@'.$timestamp);

is created, the time zone of the object is always +00:00 or UTC. Even if a time zone is specified when the object is created, this is ignored when a timestamp is used.

$timestamp = 1423522800;  // Timestamp for 2015-02-10
$date1 = DateTime::createFromFormat('U', $timestamp, new DateTimeZone('Europe/Madrid'));

var_dump($date1);

Output:

object(DateTime)#3 (3) {
  ["date"]=>
  string(26) "2015-02-09 23:00:00.000000"
  ["timezone_type"]=>
  int(1)
  ["timezone"]=>
  string(6) "+00:00"
}

To get the local time, the time zone has to be set after the DateTime has been created.

$date = date_create('@1423522800')
  ->setTimeZone(new DateTimeZone('Europe/Madrid'));

var_dump($date);

Now the object has the expected time and time zone.

object(DateTime)#2 (3) {
  ["date"]=>
  string(26) "2015-02-10 00:00:00.000000"
  ["timezone_type"]=>
  int(3)
  ["timezone"]=>
  string(13) "Europe/Madrid"
}
Sign up to request clarification or add additional context in comments.

2 Comments

Is it possible to DateTime::createFromFormat() use date_default_timzone_get() on format() without setTimezone(...) ?
As far as I know not. A time zone parameter and a current time zone in the date-expression are always ignored if the date-expression contains a UNIX timestamp.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.