Я храню даты в базе данных 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('Ymd H:i:s', strtotime($Site->getUTCOffset() . ' hours', strtotime(date($utcDate))));
Есть ли более короткий путь?
Вот что мы сделали с нашими серверами. Мы установили все, чтобы использовать UTC, и мы показываем в часовом поясе пользователя, перейдя с UTC на лету. Код внизу этого сообщения – пример того, как заставить это работать; вы должны подтвердить, что он работает во всех случаях с вашей настройкой (например, с летнего времени и т. д.).
/etc/sysconfig/clock
и установите ZONE
в UTC
ln -sf /usr/share/zoneinfo/UTC /etc/localtime
Импортируйте время в MySQL при необходимости:
mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root -p mysql
Измените my.cnf и добавьте следующее в раздел [mysqld]:
default-time-zone = 'UTC'
<?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('Ymd 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 / TimeZone ?
<?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('Ymd H:i:s'); }
http://richardwillia.ms/blog/2011/04/time-zone-conversion-using-datetime-class/
Надеюсь, это поможет.
Потратив много времени на эту проблему, не пытайтесь самостоятельно выполнять трансляцию часового пояса. Это королевский PIA, чреватый трудностями, и очень сложно понять это на международном уровне.
Тем не менее, наилучшим вариантом является преобразование вашего времени d в d в MySQL в timestamp s и просто использование базы данных для преобразования времени:
mysql> set time_zone='America/New_York';
timestamp s в MySQL меньше, а поддержка перевода часового пояса. datetime нет.
Прежде чем отображать информацию о сайте на странице, просто вызовите указанную выше команду, и она будет корректно отображаться без каких-либо изменений кода PHP.
Предостережения:
Чтобы отключить свойства метки времени :
ALTER TABLE mytable CHANGE COLUMN Created Created timestamp NULL DEFAULT 0;
DEFAULT 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('Ymd 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 ?>
ADDTIME($utcDate,$Site->getUTCOffset())
Это сработало для меня, и это довольно чисто
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');