25

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?

jimy
  • 4,848
  • 3
  • 35
  • 52

6 Answers6

44

The answer provided by Volkerk (that says timestamps are meant to be always UTC based) is correct, but if you really need a workaround (to make timezone based timestamps) 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

Top-Master
  • 7,611
  • 5
  • 39
  • 71
Cecil Zorg
  • 1,478
  • 13
  • 15
  • 1
    It's possibly confusing to use a workaround like this as you risk getting into all sorts of trouble with timezones vs the unix timestamp. Given the OP specified an output format would it be better to use DateTime's format method, i.e. $date->format('Y-m-d H:i:s') – liquorvicar Dec 29 '11 at 13:27
  • 1
    I agree with you totally, and I would not recommend this. Storing as unix timestamp would be better and when displaying the data convert to correct timezone. If the user is going to store this information in a database I would discard the unix timestamp format completely and go for a datetime database type (because of the different datetime/functions that will make your live easier) – Cecil Zorg Dec 29 '11 at 13:33
  • Is this right - `$date = new DateTime(null, new DateTimeZone('Philippines'));` . I only want to get from PH. – RoCkDevstack Jun 22 '16 at 11:39
  • Replace: 'Philippines' with: 'Asia/Manila' – Cecil Zorg Jun 22 '16 at 13:25
27

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.

VolkerK
  • 95,432
  • 20
  • 163
  • 226
  • 2
    I want the time stamp of 'now' according to timezone, any work around for this – jimy Dec 29 '11 at 13:08
  • you'd have to store the timestamp _and_ the timezone id. Or you store another date/time representation which may or may not include the timezone, e.g. as ISO 8601 date – VolkerK Dec 29 '11 at 13:25
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);
3

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();
Iliya Kolev
  • 406
  • 3
  • 4
  • 1
    citing **`kim.jongwook`** who suggested the same on [`php.net` forums](https://www.php.net/manual/en/class.datetime.php#125378) – y2k-shubham Jan 07 '21 at 20:48
  • 1
    kim.jongwook suggestion is 3 months old. Mine is over a year... You mean he is citing me? :) fine by me – Iliya Kolev Jan 08 '21 at 21:31
2

The unix timestamp that you get with time() is not influenced in anyway by the timezone. The timezone is relevant when you want to get the unix timestamp of a given date like 2022-09-11 13:00, or when you want to display the unix timestamp in a calendar fashion.

So if you want to get the unix timestamp of a given date in a certain timezone, use the strtotime() function and include the timezone parameter.

$unixTimestampOfDate = strtotime('2022-09-11 13:00 Europe/Berlin');

If you want to display a unix timestamp in a calendar fashion considering a given timezone, set the timezone default and then use the date() function.

date_default_timezone_set('Europe/Berlin');
echo date('Y-m-d H:i', $unixTimestamp);
jparty
  • 68
  • 8
0

Here is a function to convert unix/gmt/utc timestamp to required timezone.

function unix_to_local($timestamp, $timezone){
    // Create datetime object with desired timezone
    $local_timezone = new DateTimeZone($timezone);
    $date_time = new DateTime('now', $local_timezone);
    $offset = $date_time->format('P'); // + 05:00

    // Convert offset to number of hours
    $offset = explode(':', $offset);
    if($offset[1] == 00){ $offset2 = ''; }
    if($offset[1] == 30){ $offset2 = .5; }
    if($offset[1] == 45){ $offset2 = .75; }
    $hours = ($offset[0] . $offset2) + 0;

    // Convert hours to seconds
    $seconds = $hours * 3600;

    // Add/Subtract number of seconds from given unix/gmt/utc timestamp
    $result = floor( $timestamp + $seconds );

    return $result;
}
MR_AMDEV
  • 1,712
  • 2
  • 21
  • 38
  • 1
    Thanks for function. But you should update the following line for newest PHP versions. $hours = ($offset[0] . $offset2) + 0; – Alper AKPINAR Dec 13 '21 at 09:12