Convert UTC dates to local time in PHP
I'm storing the UTC dates into the DB using:
$utc = gmdate("M d Y h:i:s A");
and t开发者_JAVA技巧hen I want to convert the saved UTC date to the client's local time.
How can I do that?
Thanks
If by client, you mean browser, then you first need to send the timezone name to PHP from the browser, then do the conversion as described below.
Answer
Convert the UTC datetime to America/Denver
// create a $dt object with the UTC timezone
$dt = new DateTime('2016-12-12 12:12:12', new DateTimeZone('UTC'));
// change the timezone of the object without changing its time
$dt->setTimezone(new DateTimeZone('America/Denver'));
// format the datetime
$dt->format('Y-m-d H:i:s T');
This works with dates after 2032, daylight savings and leap seconds and does not depend on the host machine locale or timezone.
It uses the timezonedb to do the calculation, this db changes over time as timezone rules change and has to be kept up to date. (see notes at the bottom)
To convert the UTC date to the server (local) time, you can use DateTime
without the second argument, which defaults to the server timezone.
// create a $dt object with the UTC timezone
$dt = new DateTime('2016-12-12 12:12:12', new DateTimeZone('UTC'));
// get the local timezone
$loc = (new DateTime)->getTimezone();
// change the timezone of the object without changing its time
$dt->setTimezone($loc);
// format the datetime
$dt->format('Y-m-d H:i:s T');
Answer 2
I recommend using DateTimeImmutable
because it doesn't mutate variables (doesn't change them behind the scenes), otherwise it works just like DateTime
.
// create a $dt object with the UTC timezone
$dt_utc = new DateTimeImmutable('2016-12-12 12:12:12', new DateTimeZone('UTC'));
// Create a new instance with the new timezone
$dt_denver = $dt_utc->setTimezone(new DateTimeZone('America/Denver'));
// format the datetime
$dt_denver->format('Y-m-d H:i:s T');
Immutability allows you to use chaining multiple times without changing the value of $dt
$dt = new DateTimeImmutable('2016-12-12 12:12:12', new DateTimeZone('UTC'));
// Format $dt in Denver timezone
echo $dt->setTimezone(new DateTimeZone('America/Denver'))->format('Y-m-d H:i:s T');
// Format $dt in Madrid timezone
echo $dt->setTimezone(new DateTimeZone('Europe/Madrid'))->format('Y-m-d H:i:s T');
// Format $dt in Local server timezone
echo $dt->setTimezone((new DateTime())->getTimezone())->format('Y-m-d H:i:s T');
Notes
time()
returns the unix timestamp, which is a number, it has no timezone.
date('Y-m-d H:i:s T')
returns the date in the current locale timezone.
gmdate('Y-m-d H:i:s T')
returns the date in UTC
date_default_timezone_set()
changes the current locale timezone
to change a time in a timezone
// create a $dt object with the America/Denver timezone
$dt = new DateTime('2016-12-12 12:12:12', new DateTimeZone('America/Denver'));
// change the timezone of the object without changing it's time
$dt->setTimezone(new DateTimeZone('UTC'));
// format the datetime
$dt->format('Y-m-d H:i:s T');
here you can see all the available timezones
https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
here are all the formatting options
http://php.net/manual/en/function.date.php
Update PHP timezone DB (in linux)
sudo pecl install timezonedb
Because of daylight savings, some dates repeat in some timezones, for example, in the United States, March 13, 2011 2:15am never occurred, while November 6, 2011 1:15am occurred twice. These datetimes can't be accurately determined.
PHP's strtotime
function will interpret timezone codes, like UTC. If you get the date from the database/client without the timezone code, but know it's UTC, then you can append it.
Assuming you get the date with timestamp code (like "Fri Mar 23 2012 22:23:03 GMT-0700 (PDT)", which is what Javascript code ""+(new Date())
gives):
$time = strtotime($dateWithTimeZone);
$dateInLocal = date("Y-m-d H:i:s", $time);
Or if you don't, which is likely from MySQL, then:
$time = strtotime($dateInUTC.' UTC');
$dateInLocal = date("Y-m-d H:i:s", $time);
Here I am sharing the script, convert UTC timestamp to Indian timestamp:-
// create a $utc object with the UTC timezone
$IST = new DateTime('2016-12-12 12:12:12', new DateTimeZone('UTC'));
// change the timezone of the object without changing it's time
$IST->setTimezone(new DateTimeZone('Asia/Kolkata'));
// format the datetime
echo $IST->format('Y-m-d H:i:s T');
Date arithmetic is not needed if you just want to display the same timestamp in different timezones:
$format = "M d, Y h:ia";
$timestamp = gmdate($format);
date_default_timezone_set("UTC");
$utc_datetime = date($format, $timestamp);
date_default_timezone_set("America/Guayaquil");
$local_datetime = date($format, $timestamp);
date()
and localtime()
both use the local timezone for the server unless overridden; you can override the timezone used with date_default_timezone_set()
.
http://www.php.net/manual/en/function.date-default-timezone-set.php
http://us3.php.net/manual/en/function.date.php
http://php.net/manual/en/function.localtime.php
First, get the date in UTC -- you've already done that so this step would really just be a database call:
$timezone = "UTC";
date_default_timezone_set($timezone);
$utc = gmdate("M d Y h:i:s A");
print "UTC: " . date('r', strtotime($utc)) . "\n";
Next, set your local time zone in PHP:
$timezone = "America/Guayaquil";
date_default_timezone_set($timezone);
And now get the offset in seconds:
$offset = date('Z', strtotime($utc));
print "offset: $offset \n";
Finally, add the offset to the integer timestamp of your original datetime:
print "LOCAL: " . date('r', strtotime($utc) + $offset) . "\n";
I store date in the DB in UTC format but then I show them to the final user in their local timezone
// retrieve
$d = (new \DateTime($val . ' UTC'))->format('U');
return date("Y-m-d H:i:s", $d);
Here is a straight way to convert the UTC time of the questioner to local time. This is for a stored time in a database etc., i.e. any time. You just have to find the time difference between UTC time and the local time you are interested in and then ajust the stored UTC time adding to it the difference.
$df = "G:i:s"; // Use a simple time format to find the difference
$ts1 = strtotime(date($df)); // Timestamp of current local time
$ts2 = strtotime(gmdate($df)); // Timestamp of current UTC time
$ts3 = $ts1-$ts2; // Their difference
You can then add this difference to the stored UTC time. (In my place, Athens, the difference is exactly 5:00:00)
Example:
$time = time() // Or any other timestamp
$time += $ts3 // Add the difference
$dateInLocal = date("Y-m-d H:i:s", $time);
Given a local timezone, such as 'America/Denver', you can use DateTime class to convert UTC timestamp to the local date:
$timestamp = *********;
$date = new DateTime("@" . $timestamp);
$date->setTimezone(new DateTimeZone('America/Denver'));
echo $date->format('Y-m-d H:i:s');
$UTC_Time = "2018-07-06 06:06:16";
echo "UTC Time ".$UTC_Time;
$Indian_Time = TimeConverion($UTC_Time);
echo "<br> Indian_Time ".$Indian_Time;
function TimeConverion($UTC_Time) {
date_default_timezone_set('Europe/London');
$sTime = date("Y-m-d h:i:sa");
$ts3 = strtotime(date("G:i:s"))-strtotime($sTime);
$utc = explode(" ",$UTC_Time);
$time = strtotime($utc[1]);
date_default_timezone_set("Asia/Calcutta");
$time += $ts3; // Add the difference
return $utc[0]." ".date("H:i:s", $time);
}
Convert date in UTC to local time or another timezone in one line.
time in UTC: "2021-09-13 16:30:16"
output timezone: 'America/Havana'
(new DateTime('2021-09-13 16:30:16', new DateTimeZone('UTC')))
->setTimezone(new DateTimeZone('America/Havana'))
->format('Y-m-d H:i:s')
精彩评论