Как я могу легко конвертировать даты из 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и setZONEtoUTC
- 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');
