Как я могу легко конвертировать даты из UTC через PHP?
Я храню даты в базе данных MySQL в полях datetime в UTC. Я использую PHP, и я вызвал date_timezone_set('UTC'), чтобы все вызовы date() (без метки времени) возвращали дату в UTC.
затем у меня есть это, чтобы данный веб-сайт мог выбрать свой часовой пояс. Теперь я хочу, чтобы даты отображались в часовом поясе сайта. Итак, если у меня есть дата, хранящаяся как "2009-04-01 15:36:13", она должна отображаться для пользователя в часовом поясе PDT (-7 часов) как "2009-04-01 08:36:13".
что является ли самый простой (наименее кодовый) метод для этого через PHP? До сих пор все, о чем я думал, это
date('Y-m-d H:i:s', strtotime($Site->getUTCOffset() . ' hours', strtotime(date($utcDate))));
есть ли более короткий путь?
8 ответов
вот что мы сделали с наших серверов. Мы устанавливаем все, чтобы использовать UTC, и мы показываем в часовом поясе пользователя, конвертируя из UTC на лету. Код в нижней части этого сообщения является примером того, как заставить это работать; вы должны подтвердить, что он работает во всех случаях с вашей настройкой (т. е. летнее время и т. д.).
Настройка CentOS
- редактировать
/etc/sysconfig/clock
и setZONE
toUTC
ln -sf /usr/share/zoneinfo/UTC /etc/localtime
настройка В MySQL
-
импорт часовых поясов в MySQL при необходимости:
mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root -p mysql
-
редактировать мои.cnf и добавьте следующее В разделе [mysqld]:
default-time-zone = 'UTC'
PHP-кода
<?php
/*
Example usage:
$unixtime = TimeUtil::dateTimeToTimestamp('2009-04-01 15:36:13');
echo TimeUtil::UTCToPST("M d, Y - H:i:s", $unixtime);
*/
// You should move this to your regular init method
date_default_timezone_set('UTC'); // make this match the server timezone
class TimeUtil {
public static function timestampToDateTime($timestamp) {
return gmdate('Y-m-d H:i:s', $timestamp);
}
public static function dateTimeToTimestamp($dateTime) {
// dateTimeToTimestamp expects MySQL format
// If it gets a fully numeric value, we'll assume it's a timestamp
// You can comment out this if block if you don't want this behavior
if(is_numeric($dateTime)) {
// You should probably log an error here
return $dateTime;
}
$date = new DateTime($dateTime);
$ret = $date->format('U');
return ($ret < 0 ? 0 : $ret);
}
public static function UTCToPST($format, $time) {
$dst = intval(date("I", $time));
$tzOffset = intval(date('Z', time()));
return date($format, $time + $tzOffset - 28800 + $dst * 3600);
}
}
почему бы не использовать встроенный в DateTime / Часовой Пояс функциональность?
<?php
$mysqlDate = '2009-04-01 15:36:13';
$dateTime = new DateTime ($mysqlDate);
$dateTime->setTimezone(new DateTimeZone('America/Los_Angeles'));
?>
Класс DateTime:http://us3.php.net/manual/en/class.datetime.php Класс DateTimeZone:http://us3.php.net/manual/en/class.datetimezone.php
поддерживаемые часовые пояса PHP:http://php.net/manual/en/timezones.php
что вы делаете это правильный способ делать вещи. Я бы рекомендовал придерживаться работы только в UTC и просто конвертировать в последнюю минуту для отображения.
вот быстрая функция, которую я собрал для преобразования часового пояса, используя класс DateTime, который поставляется с PHP. Это немного больше кода, чем у вас есть, но я думаю, что это проще и лучший способ структурирования вещи...
function convert_time_zone($date_time, $from_tz, $to_tz)
{
$time_object = new DateTime($date_time, new DateTimeZone($from_tz));
$time_object->setTimezone(new DateTimeZone($to_tz));
return $time_object->format('Y-m-d H:i:s');
}
http://richardwillia.ms/blog/2011/04/time-zone-conversion-using-datetime-class/
надеюсь, что это поможет.
потратив много времени на решение этой проблемы,не пытайтесь самостоятельно реализовать перевод часовых поясов. это королевский PIA, чреватый трудностями, и это очень трудно получить его прямо на международном уровне.
тем не менее, лучший вариант-конвертировать ваш datetimes в MySQL для меткаs, и просто использовать базу данных для преобразования раз:
mysql> set time_zone='America/New_York';
меткаs в MySQL меньше, и поддержка перевод часовых поясов. datetime нет.
прежде чем отображать информацию о сайте на странице, просто вызовите вышеуказанную команду, и она будет отображаться правильно без каких-либо изменений кода PHP вообще.
предостережения:
- если вы используете сейчас() или любые функции местного времени, вы должны обновить их до UTC_TIMESTAMP ()
- меткаs имеют интересные свойства обновления и вставки, которые возможно, вы захотите выключить.
выключить метка свойства:
ALTER TABLE mytable CHANGE COLUMN Created Created timestamp NULL DEFAULT 0;
на по умолчанию 0 отключает обновление столбца при обновлении других столбцов.
<?php
function getNoteDateTimeZone($date = null, $from_dtz = 'US/Central', $to_dtz = null) {
//$from_zt = 'US/Central'; // Time Zone = -06:00
if (is_null($date) == FALSE && is_null($from_dtz) == FALSE && is_null($to_dtz) == FALSE) {
// set TimeZone from
$time_object = new DateTime($date, new DateTimeZone($from_dtz));
$time_now_object = new DateTime("now", new DateTimeZone($from_dtz));
// Change TimeZone
$time_object->setTimezone(new DateTimeZone(trim($to_dtz)));
$time_now_object->setTimezone(new DateTimeZone(trim($to_dtz)));
// Is day = day in $time_now_object, $time_object..?
if ($time_now_object->format('d') == $time_object->format('d')) {
return $time_object->format('H:i:s');
} else {
return $time_object->format('Y-m-d H:i:s');
}
} else {
return '';
}
}
?>
использовать пример:
<?php
$date = '2008-06-02 20:32:46';
$dtz = 'America/Argentina/Buenos_Aires';
echo getNoteDateTimeZone($date, 'US/Central', $dtz); // Out = 2008-06-02 23:32:46
?>
это работает для меня и это довольно чистый!--2-->
function convert_to_user_date($date, $userTimeZone = 'America/Los_Angeles', $serverTimeZone = 'UTC', $format = 'n/j/Y g:i A')
{
$dateTime = new DateTime ($date, new DateTimeZone($serverTimeZone));
$dateTime->setTimezone(new DateTimeZone($userTimeZone));
return $dateTime->format($format);
}
function convert_to_server_date($date, $userTimeZone = 'America/Los_Angeles', $serverTimeZone = 'UTC', $format = 'n/j/Y g:i A')
{
$dateTime = new DateTime ($date, new DateTimeZone($userTimeZone));
$dateTime->setTimezone(new DateTimeZone($serverTimeZone));
return $dateTime->format($format);
}
преобразовать часовой пояс пользователя на сервере. и наоборот, с единственной функцией:
function convertTimeZone($date, $convertTo = 'userTimeZone', $userTimeZone = 'America/Los_Angeles', $serverTimeZone = 'UTC', $format = 'n/j/Y g:i A')
{
if($convertTo == 'userTimeZone'){
$dateTime = new DateTime ($date, new DateTimeZone($serverTimeZone));
$dateTime->setTimezone(new DateTimeZone($userTimeZone));
return $dateTime->format($format);
} else if($convertTo == 'serverTimeZone'){
$dateTime = new DateTime ($date, new DateTimeZone($userTimeZone));
$dateTime->setTimezone(new DateTimeZone($serverTimeZone));
return $dateTime->format($format);
}
}
echo convertTimeZone(date('Ydm h:i:s'),'serverTimeZone');