66

Can anyone suggest an easy method to convert date and time to different timezones in php?

BlitZ
  • 12,038
  • 3
  • 49
  • 68
raki
  • 2,253
  • 8
  • 33
  • 42

9 Answers9

138

You can use the datetime object or their function aliases for this:

Example (abridged from PHP Manual)

date_default_timezone_set('Europe/London');

$datetime = new DateTime('2008-08-03 12:35:23');
echo $datetime->format('Y-m-d H:i:s') . "\n";
$la_time = new DateTimeZone('America/Los_Angeles');
$datetime->setTimezone($la_time);
echo $datetime->format('Y-m-d H:i:s');

Edit regarding comments

but i cannt use this method because i need to show date in different time zones as the user login from different locations

That's not a problem. When a user logs in, you determine his timezone and set it to your DateTime object just like shown. I'm using a similar approach in one of my projects and it works like a charm.

in the database i need to get the dates in any single timezone, then only it can be processed properly

You store the time either as a timestamp or a datetime in one timezone. When you query a DateTime field, you either convert the time in a DateTime object to this timezone or - if your db supports it - query with the selected timezone.

datagutten
  • 163
  • 1
  • 9
Gordon
  • 312,688
  • 75
  • 539
  • 559
  • thanks Gordon but i cannt use this method because i need to show date in different time zones as the user login from different locations – raki Mar 24 '10 at 06:25
  • 1
    @raki: so just after user is logged in - set up date_default_timezone_set() with proper user's selected timezone. – zerkms Mar 24 '10 at 06:44
  • that is also not possible.. because.. in the database i need to get the dates in any single timezone, then only it can be processed properly – raki Mar 24 '10 at 06:51
  • 13
    In the database you store everything in GMT. Either that, or it becomes an unmanageable mess. – Jacco Mar 24 '10 at 10:08
  • 1
    all this is more complicated than it needs to be. if i set the default timezone, then the date('Y-m-d H:i:s') bit that i do to get the created/updated times will be in the user timezone. So I have to convert them to UTC. Lots of changes everywhere, making sure that i am not doing the conversion twice. This is really an impedance mismatch. – Kinjal Dixit Nov 24 '12 at 06:22
  • Although it may not be obvious at first, the H for hour does matter. If you skim over it and use a format not in 24 hour e.g. 'Y-m-d H:i:s' vs. 'Y-m-d h:i:s', you can get an erroneous result where it calculates the hour as being AM. Just make sure you're using a format that takes that into consideration like the example above. – Alan Fullmer Jan 09 '22 at 22:52
23

An even simpler method looks like this:

date_default_timezone_set('Europe/London'); // your user's timezone
$my_datetime='2013-10-23 15:47:10';
echo date('Y-m-d H:i:s',strtotime("$my_datetime UTC"));

As described in the PHP manual, strtotime() accepts a timezone too, you just have to append it to your datetime.

I recommend you to store all your datetimes in UTC because that way you won't have problems with the daylight savings.

soger
  • 1,147
  • 10
  • 18
17

This worked for me and it's pretty clean too!

function convert_to_user_date($date, $format = 'n/j/Y g:i A', $userTimeZone = 'America/Los_Angeles', $serverTimeZone = 'UTC')
{
    try {
        $dateTime = new DateTime ($date, new DateTimeZone($serverTimeZone));
        $dateTime->setTimezone(new DateTimeZone($userTimeZone));
        return $dateTime->format($format);
    } catch (Exception $e) {
        return '';
    }
}

function convert_to_server_date($date, $format = 'n/j/Y g:i A', $userTimeZone = 'America/Los_Angeles', $serverTimeZone = 'UTC')
{
    try {
        $dateTime = new DateTime ($date, new DateTimeZone($userTimeZone));
        $dateTime->setTimezone(new DateTimeZone($serverTimeZone));
        return $dateTime->format($format);
    } catch (Exception $e) {
        return '';
    }
}

//example usage
$serverDate = $userDate = '2014-09-04 22:37:22';
echo convert_to_user_date($serverDate);
echo convert_to_server_date($userDate);
saada
  • 2,612
  • 3
  • 27
  • 33
15

None of these answers worked for me (I skipped trying code that was overly bulky in size). I also think it's weird to change the default timezone just for a single conversion.

Here is my solution:

function changeTimeZone($dateString, $timeZoneSource = null, $timeZoneTarget = null)
{
  if (empty($timeZoneSource)) {
    $timeZoneSource = date_default_timezone_get();
  }
  if (empty($timeZoneTarget)) {
    $timeZoneTarget = date_default_timezone_get();
  }

  $dt = new DateTime($dateString, new DateTimeZone($timeZoneSource));
  $dt->setTimezone(new DateTimeZone($timeZoneTarget));

  return $dt->format("Y-m-d H:i:s");
}

So, to convert to the server default, you would just pass one timezone:

changeTimeZone("2016-10-24 16:28", "Asia/Tokyo");

To convert from the server default to the user, you would leave the 2nd parameter null or blank:

changeTimeZone("2016-10-24 16:28", "", "Asia/Tokyo");

And to switch between 2 timezones unrelated to the default, you would provide 2 timezones:

changeTimeZone("2016-10-24 16:28", "America/New_York", "Asia/Tokyo");
Skeets
  • 4,476
  • 2
  • 41
  • 67
  • 2
    Nice answer. I prefer try catch instead of is(empty) to avoid any spelling errors in timezone string. try{ new DateTimeZone($timeZoneSource); } catch(Exception $e){ $timeZoneSource = date_default_timezone_get(); } – Ajay Singh Jan 13 '18 at 19:13
7

UTC to local:

<?php
$datetime = date("Y-m-d H:i:s");
$utc = new DateTime($datetime, new DateTimeZone('UTC'));
$utc->setTimezone(new DateTimeZone('America/Sao_Paulo'));
echo $utc->format('Y-m-d H:i:s');

?>
5

DateTime::setTimezone -- date_timezone_set — Sets the time zone for the DateTime object

Object oriented style

<?php
$date = new DateTime('2000-01-01', new DateTimeZone('Pacific/Nauru'));
echo $date->format('Y-m-d H:i:sP') . "\n";

$date->setTimezone(new DateTimeZone('Pacific/Chatham'));
echo $date->format('Y-m-d H:i:sP') . "\n";
?>

Procedural style

<?php
$date = date_create('2000-01-01', timezone_open('Pacific/Nauru'));
echo date_format($date, 'Y-m-d H:i:sP') . "\n";

date_timezone_set($date, timezone_open('Pacific/Chatham'));
echo date_format($date, 'Y-m-d H:i:sP') . "\n";
?>

The above examples will output:

2000-01-01 00:00:00+12:00
2000-01-01 01:45:00+13:45
itsazzad
  • 6,868
  • 7
  • 69
  • 89
2
// Convert date from one zone to another..
/* 
$zone_from='Asia/Kolkata';

$zone_to='America/Phoenix';

date_default_timezone_set($zone_from);

$convert_date="2016-02-26 10:35:00";

echo $finalDate=zone_conversion_date($convert_date, $zone_from, $zone_to);

*/
function zone_conversion_date($time, $cur_zone, $req_zone)
{   
    date_default_timezone_set("GMT");
    $gmt = date("Y-m-d H:i:s");
    
    date_default_timezone_set($cur_zone);
    $local = date("Y-m-d H:i:s");
  
    date_default_timezone_set($req_zone);
    $required = date("Y-m-d H:i:s");
    
    /* return $required; */
    $diff1 = (strtotime($gmt) - strtotime($local));
    $diff2 = (strtotime($required) - strtotime($gmt));

    $date = new DateTime($time);
    $date->modify("+$diff1 seconds");
    $date->modify("+$diff2 seconds");

    return $timestamp = $date->format("Y-m-d H:i:s");
}
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
user2801665
  • 117
  • 1
  • 3
1
<?php
$time='6:02';
$dt = new DateTime($time, new DateTimeZone('America/New_York'));
//echo $dt->format('Y-m-d H:i:s') . PHP_EOL;
$dt->setTimezone(new DateTimeZone('Asia/Kolkata'));
echo $dt->format('H:i') . PHP_EOL; 
?>
Hara Prasad
  • 704
  • 6
  • 15
0
 Try this:    
 function convertDate($dt, $timeZone) {    
        $UTC = new DateTimeZone("UTC");
        $date= date('Y-m-d H:i:s', strtotime($dt)); 
        $dateConv = new DateTime( $dt, $UTC  );
        $dateFormat ='m/d/Y h:i A';
        $date->setTimezone(new DateTimeZone($timeZone));
        return $date->format($dateFormat);
    }
Nilesh
  • 97
  • 5