How to get Unix timestamp in php based on timezone

2019-01-14 08:19发布

问题:

Code first

    echo time() . '<br/>';
echo date('Y-m-d H:i:s') . '<br/>';
date_default_timezone_set('America/New_York'); 

echo time() . '<br/>';
print_r($timezones[$timezone] . '<br/>');
echo date('Y-m-d H:i:s') . '<br/>';

In the above code the date is printed according to timezone but unix timestamp is same even after setting default timezone

How can we print unix timestamp according to timezone?

回答1:

The answer provided by Volkerk is correct, but if you really need a work around look at my example.

<?php

//default timezone
$date = new DateTime(null);
echo 'Default timezone: '.$date->getTimestamp().'<br />'."\r\n";

//America/New_York
$date = new DateTime(null, new DateTimeZone('America/New_York'));
echo 'America/New_York: '.$date->getTimestamp().'<br />'."\r\n";

//Europe/Amsterdam
$date = new DateTime(null, new DateTimeZone('Europe/Amsterdam'));
echo 'Europe/Amsterdam: '.$date->getTimestamp().'<br />'."\r\n";

echo 'WORK AROUND<br />'."\r\n";
// WORK AROUND
//default timezone
$date = new DateTime(null);
echo 'Default timezone: '.($date->getTimestamp() + $date->getOffset()).'<br />'."\r\n";

//America/New_York
$date = new DateTime(null, new DateTimeZone('America/New_York'));
echo 'America/New_York: '.($date->getTimestamp() + $date->getOffset()).'<br />'."\r\n";

//Europe/Amsterdam
$date = new DateTime(null, new DateTimeZone('Europe/Amsterdam'));
echo 'Europe/Amsterdam: '.($date->getTimestamp() + $date->getOffset()).'<br />'."\r\n";
?>

Get the regular timestamp and add the UTC offset



回答2:

https://en.wikipedia.org/wiki/Unix_time

Unix time, or POSIX time, is a system for describing instants in time, defined as the number of seconds elapsed since midnight Coordinated Universal Time (UTC) of Thursday, January 1, 1970

The unix timestamp isn't affected by a timezone setting. Setting the timezone only affects the interpretation of the timestamp value.



回答3:

Had the same issue myself, and this is the easiest approach I could do fairly quickly.

$dateTimeZone = new DateTimeZone("America/New_York");
$dateTime = new DateTime("now", $dateTimeZone);
$timeOffset = $dateTimeZone->getOffset($dateTime);

// New time since epoch according to timezone
$newTime = time() + $timeOffset;

echo date("H:i:s", $newTime);


回答4:

Saw the answers with the offset solution and I think that unless you save you times in the database in UTC or Unix timestamp they won't help. The problem, when it comes to getTimestamp(), is that the timezone is not considered even when you initiate the object... How do I explain it :)... let's say you have some event with date and time in you db. You also have you timezone correctly configured. I'll put these in vars for this example, so it's more visible:

$dateTime = '25.08.2018 16:45:15';//some event in your db //can be any valid format
$localTimezone = 'Europe/Berlin';
$dateTimeLocal = new \DateTime($dateTime, new \DateTimeZone($localTimezone));
var_dump($dateTimeLocal->getTimestamp());`

Now...when you do this, you pass the datetime and your timezone to the constructor. What you would expect is that php respects your timezone and you get UTC timestamp that corresponds to 16:45 in Berlin which would be UTC 15:45 in winter and UTC 14:45 in summer. It won't happen - what you get is timestamp corresponding to UTC 16:45. If you add the offset now you will be hour or two off.

The correct way to do this is to initiate the object, set/switch timezones, create a formatted datetime which respects the timezone and then get timestamp from the formatted datetime. It might be a bit slower, but it's timezone fail prove:

$date = '25.08.2018 16:45:15';//some event in your db //can be any valid format
$format = 'Y-m-d H:i:s';//just a format we will use for this example //also can be any valid format
$localTimezone = 'Europe/Berlin';
$remoteTimezone = 'America/Lima';
$dateTime = new \DateTime($date, new \DateTimeZone($localTimezone));
$dateTime->setTimezone(new \DateTimeZone($remoteTimezone));
$timestampLima = DateTime::createFromFormat($format, $dateTime->format($format))->getTimestamp();