DateTime :: diff () не зависит от часовой пояс, но всегда возвращает одинаковое значение

Я добавляю данные на основе аукциона в свою систему. Например:

user's timezone is : `America/Denver` auction start time is : Thu, 21 Jun 2012 03:46:22 AM auction period : 1 day. auction end time : Fri, 22 Jun 2012 03:46:22 AM 

Я сохраняю всю эту информацию так же, как и в моей БД (т. Е. Все сохраненное время, основанное на часовом поясе пользователя ).

Теперь я хочу фактическую разницу между временем окончания и текущим временем (часовой пояс Америки / Денвера).

Я использовал функции DateTime()

поэтому даже я не конвертирую часовой пояс; он возвращает ту же разницу (и это тоже неправильно).

Мой PHP-код ниже; вы также можете найти его в CodePad

 $end_time = 'Fri, 22 Jun 2012 03:46:22 AM'; $tz = 'America/Denver'; dateDifference($end_time,$tz); function dateDifference($end, $tz = NULL) { $owner_tz = new DateTimeZone($tz); //var_dump($owner_tz->getName()); $from = new DateTime("now", new DateTimeZone('GMT')); $from ->setTimeZone($owner_tz); $to = new DateTime($end,new DateTimeZone('GMT')); /* @Note:I have commented below setTimeZone() because I have already stored * `end time` as per user's timezone, So I dont need to convert it again * into user's timezone.you can un-comment below line. * it doesn't affect the results anyways. */ //$to ->setTimeZone($owner_tz); //procedural style using date_diff() $interval = date_diff($from, $to); var_dump($interval); // OO style using dateTime::diff() $interval = $from->diff($to); var_dump($interval); } 

Возвращает:

 object(DateInterval)[4] public 'y' => int 0 public 'm' => int 0 public 'd' => int 0 public 'h' => int 16 public 'i' => int 40 public 's' => int 24 public 'invert' => int 0 public 'days' => int 6015 

Рекомендации:

  • DateTime()
  • DateTime::diff
  • DateTime::setTimeZone
  • Обработка изменения часового пояса с помощью PHP DateTime

В следующих строках вы в основном говорите, что дата окончания находится в GMT, пока она должна быть в Америке / Денвере:

 $to = new DateTime($end, new DateTimeZone('GMT')); 

Затем вы намерены преобразовать его в Америку / Денвер, но с тех пор, как вы создали дату с использованием часовой пояс GMT, это было бы неправильно в любом случае.

 // $to ->setTimeZone($owner_tz); 

Это создаст дату окончания, используя часовой пояс пользователей, который, вероятно, вы ищете:

 $to = new DateTime($end, $owner_tz); 

Я получил решение, поэтому я хотел бы поделиться

Фактически я установил часовой пояс по умолчанию в файле config.inc.php как config.inc.php ниже

date_default_timezone_set('America/Los_Angeles');

то я проверяю текущее время и часовой пояс сервера MySQL из phpmyadmin с нижестоящим запросом

 SELECT NOW(), SYSDATE(), @@global.time_zone , @@session.time_zone , TIMEDIFF( NOW( ) , CONVERT_TZ( NOW( ) , @@session.time_zone , '+00:00' )) AS OFFSET 

Это возвращает значение OFFSET +05: 30

шаги решения:

  • Сначала я изменил часовой пояс mySQL Server на GMT / UTC +00: 00 (у меня супер привилегия на mySQL-сервере)

     SET GLOBAL time_zone = '+00:00'; 
  • Мы сохраняем дату и время, используя start_date = NOW() (тип данных столбца: DATETIME )

Теперь есть 2 способа получить дату и время в соответствии с часовым поясом пользователя ( America/Denver )

первый метод (используя PHP DateTime )

  /* * first set timezone as GMT. * This is MUST because default timezone is differ from user timezone */ $gmt = new DateTimeZone('GMT'); $user_tz = 'America/Denver'; $st = new DateTime($row[`start_date`], $gmt); // now set user timezone $st->setTimezone($user_tz ); $stime = $qt->format('r'); echo $stime; 

второй метод (с использованием MySQL UNIX_TIMESTAMP )

 #$retrieve data from server in timestamp $qry = "SELECT `start_date`,UNIX_TIMESTAMP(`start_date`) AS sTimestamp FROM..." $st = new DateTime('@'.$row['sTimestamp ']); $stime = $st->format('r'); echo $stime; 

Примечание. Не меняйте start_date на метку времени с помощью strtotime() . Он будет возвращать другое значение из UNIX_TIMESTAMP() т.е.

  strtotime($row['start_date']) !== $row['sTimestamp']