У меня есть сервер, который настроен на EST, и все записи в базе данных установлены в EST. Я хотел бы знать, как установить его в GMT. Я хочу предложить пользователям часового пояса.
Независимо от того, в какой часовой области GMT находится сервер, здесь очень простой способ получить время и дату для любого часового пояса. Это делается с помощью функций time()
и gmdate()
. Функция gmdate()
обычно дает нам время по Гринвичу, но, делая трюк с функцией time()
мы можем получить GMT + N или GMT-N, то есть мы можем получить время для любого часового пояса GMT.
Например, если вам нужно получить время для GMT + 5, вы можете сделать это следующим образом
<?php $offset=5*60*60; //converting 5 hours to seconds. $dateFormat="dmY H:i"; $timeNdate=gmdate($dateFormat, time()+$offset); ?>
Теперь, если вам нужно получить время для GMT-5, вы можете просто вычесть смещение от time()
вместо добавления к нему, например, в следующем примере, где мы получаем время для GMT-4
<?php $offset=4*60*60; //converting 4 hours to seconds. $dateFormat="dmY H:i"; //set the date format $timeNdate=gmdate($dateFormat, time()-$offset); //get GMT date - 4 ?>
Я настоятельно рекомендую избегать возиться с отметками времени UNIX, чтобы сделать его похожим на другой часовой пояс. Это урок, который я усвоил, слишком много раз.
Временная метка – это количество секунд с полуночи 1 января 1970 года по Гринвичу. Неважно, где вы находитесь в мире, данная метка времени представляет собой тот же самый момент времени, независимо от часовых поясов. Да, отметка времени «0» означает 10 утра 1/1/70 в Австралии, Midnight 1/1/70 в Лондоне и 17:00 31/12/69 в Лос-Анджелесе, но это не означает, что вы можете просто добавить или вычесть значения и гарантировать точность.
Золотой пример, который наполнял меня каждый год слишком долго, заключался в том, что когда наступит летнее сбережение. Переход на летнее время означает, что существуют «часы», которые не существуют в некоторых частях мира. Например, в большинстве районов США 2 апреля 2006 года не было 2:01 утра.
Достаточно квази-разборчивое разглагольствование. Мой совет – хранить ваши даты в базе данных как временные метки, а затем …
date()
gmdate()
date_default_timezone_set()
а затем date()
Например,
$timestamp = time(); echo "BRISBANE: " . date('r', $timestamp) . "\n"; echo " UTC: " . gmdate('r', $timestamp) . "\n"; date_default_timezone_set('Africa/Johannesburg'); echo " JOBURG: " . date('r', $timestamp) . "\n"; // BRISBANE: Tue, 12 May 2009 18:28:20 +1000 // UTC: Tue, 12 May 2009 08:28:20 +0000 // JOBURG: Tue, 12 May 2009 10:28:20 +0200
Это сохранит ваши ценности в чистоте (вам не нужно беспокоиться о добавлении смещений, а затем вычитать перед сохранением), он будет соблюдать все правила перехода на летнее время, и вам также не нужно даже искать часовой пояс места вы хотите.
Важно отметить, что если вы используете дату («Z») для преобразования даты, которая хранится в базе данных, которую вы даете дате отметки времени в качестве второго аргумента, в противном случае ваш результат будет неточным.
например
В Великобритании иногда дата ('Z') даст 3600, иногда она будет давать 0.
echo date('Z', strtotime('2012-01-01'));
Дает 0
echo date('Z', strtotime('2012-07-01'));
Дает 3600
Таким образом, чистое использование strtotime ($ dbDateValue) – дата («Z») может быть неправильным
Вместо этого используйте:
$dbDateTimestamp = strtotime($dbDateValue); // where $dbDateValue something like 2012-01-01 22:34:00 $utcTimestamp = strtotime($dbDateTimestamp) - date('Z', $dbDateTimestamp);
Это, конечно, зависит от PHP и базы данных, которые устанавливаются в один и тот же часовой пояс.
Вот список часовых поясов, отличающихся от GMT, надеюсь, что это будет полезно!
echo '<pre>'; $zones_array = array(); $timestamp = time(); # to maintain the original timezone, store before $default_timezone = date_default_timezone_get(); foreach (timezone_identifiers_list() as $key => $zone) { date_default_timezone_set($zone); $zones_array[$key]['zone'] = $zone; $zones_array[$key]['diff_from_GMT'] = date('P', $timestamp); } # to maintain the original timezone, re-set after date_default_timezone_set($default_timezone); print_r($zones_array);
Благодаря!
Я был вдохновлен этим вопросом, чтобы написать альтернативную функцию для преобразования временной метки в необходимый часовой пояс.
Итак, процедуры CORRECT для записи, отображения (преобразования) времени:
1) record timestamp with time() 2) If you need to get a different timezone, use: 2.1) Class based: 2.1.1) DateTime class + setTimezone or 2.1.2) date_default_timezone_set() and then date() 2.1.1) is better and more flexible than 2.1.2) Function: function getLTime_class($ts, $uTZ, $format_str="Ymd H:i", $sTZ="America/Toronto"){ // $ts - timestamp recorded with time(); if have date => convert to timestamp: strtotime($date_input); //for ex strtotime('2012-02-17 12:00:00'); => 1345219200 - same value for summer and winter (for toronto timezone); // $uTZ - TZ string (ex: 'America/Toronto'); convert timestamp to this TimeZone // $sTZ - TZ string (ex: 'America/Toronto'); convert timestamp from this TimeZone $TimeZone_server=new DateTimeZone($sTZ); $date_obj=new DateTime("@$ts", $TimeZone_server); $TimeZone_local=new DateTimeZone($uTZ); $date_obj->setTimeZone($TimeZone_local); return $date_obj->format($format_str); } Usage: $date_input=$_POST['date_input']; //read from POST $ts=strtotime($date_input); //for ex strtotime('2012-02-17 12:00:00'); => 1345219200 - same value for summer and winter (for toronto timezone); $userTZ='America/Toronto'; //read from user params $result=getLTime_class($ts, $userTZ, 'Ymd H:i:s'); 2.2) Non-Class based: Function: //this function replaces the function with DateTime class. It's faster. $uTZoffset is integer. function getLTime_nonclass($ts, $uTZoffset, $format_str="Ymd H:i"){ // $ts - timestamp recorded with time(); if have date => convert to timestamp: strtotime($date_input); //for ex strtotime('2012-02-17 12:00:00'); => 1345219200 - same value for summer and winter (for toronto timezone); // $uTZoffset - TZ offset (integer) $uTZoffset must consider DTS (for ex: in summer $uTZoffset=-4; in winter $uTZoffset=-5) $ts_offset=date('Z',$ts); if ($uTZoffset) $add_offset=$ts_offset-date('Z'); //when not UTC else $add_offset=0; //when UTC return date($format_str,$ts-$ts_offset+$uTZoffset*3600+$add_offset); } Usage: $date_input=$_POST['date_input']; //read from POST $ts=strtotime($date_input); //for ex strtotime('2012-02-17 12:00:00'); => 1345219200 - same value for summer and winter (for toronto timezone); $uTZoffset=-4; //read from user params. $uTZoffset - TZ offset (integer) $uTZoffset must consider DTS (for ex: in summer $uTZoffset=-4; in winter $uTZoffset=-5) $result=getLTime_nonclass($ts, $uTZoffset, 'Ymd H:i:s');
Результаты:
$ date_input = 2012-08-17 12:00:00
Server date: summer (2013-08-26) getLTime_class => $userTZ='America/Toronto' => 2012-08-17 12:00:00 getLTime_nonclass => $uTZoffset=-4 => 2012-08-17 12:00:00 getLTime_class => $userTZ='UTC' => 2012-08-17 16:00:00 getLTime_nonclass => $uTZoffset=0 => 2012-08-17 16:00:00 Server date: winter (2013-02-26) getLTime_class => $userTZ='America/Toronto' => 2012-08-17 12:00:00 getLTime_nonclass => $uTZoffset=-5 => 2012-08-17 12:00:00 getLTime_class => $userTZ='UTC' => 2012-08-17 16:00:00 getLTime_nonclass => $uTZoffset=0 => 2012-08-17 16:00:00
$ date_input = 2012-02-17 12:00:00
Server date: summer (2013-08-26) getLTime_class => $userTZ='America/Toronto' => 2012-02-17 12:00:00 getLTime_nonclass => $uTZoffset=-4 => 2012-02-17 12:00:00 getLTime_class => $userTZ='UTC' => 2012-02-17 17:00:00 getLTime_nonclass => $uTZoffset=0 => 2012-02-17 17:00:00 Server date: winter (2013-02-26) getLTime_class => $userTZ='America/Toronto' => 2012-02-17 12:00:00 getLTime_nonclass => $uTZoffset=-5 => 2012-02-17 12:00:00 getLTime_class => $userTZ='UTC' => 2012-02-17 17:00:00 getLTime_nonclass => $uTZoffset=0 => 2012-02-17 17:00:00
Я решил использовать getLTime_nonclass, чтобы сделать преобразование быстрее, чем использование классов. Все, что я прошу, это подтвердить, что getLTime_nonclass является допустимой заменой для getLTime_class. Пожалуйста, не стесняйтесь высказать свое мнение. благодаря
Много времени есть задача, когда необходимо время записи в БД в GMT + 0, но функция time () будет возвращать время сервера. Его возможное решение следующей функцией:
/** * Converts a local Unix timestamp to GMT * * @param int Unix timestamp * @return int */ function local_to_gmt($time = '') { if ($time === '') { $time = time(); } return mktime( gmdate('G', $time), gmdate('i', $time), gmdate('s', $time), gmdate('n', $time), gmdate('j', $time), gmdate('Y', $time) ); }