2016-12-27 4 views
0

Я нахожусь на ранней стадии построения таблицы mysql, которая будет хранить данные из двух часовых поясов. Как моя машина, так и сервер находятся в часовом поясе America/Los_Angeles. Таблица часовых поясов не загружается на сервере mysql, но в другом месте на этом сайте я читал, что это не обязательно, если php обрабатывает запросы - php будет писать смещение UTC для mysql. Тип данных Mysql - TIMESTAMP. Выборочные данные были вставлены с PHP скрипт, который включает в себя следующее заявление:php mysql UTC timestamp

 if($company == 'HOS_CIN' or $company == 'HOS_FER') { 
     date_default_timezone_set("America/New_York"); 
    } 

Затем были использованы два PHP скрипты для отображения данных в браузере. Один из них включал вышеупомянутое заявление, а другое - нет. Тот, с заявлением, отображал время как полдень EST, и тот, который не отображал время как полдень PST. Если mysql сохранил смещение UTC, не должно было быть трехчасовой разницы во время отображения?

Php версии 5.3.3, MySQL версии 5.0.95

+0

1) Нет, PHP не будет печатать UTC если вы не указали это (например, установив часовой пояс в UTC) 2) 'TIMESTAMP' конвертирует из/в часовой пояс MySQL Server при хранении/получении дат, похоже, что вы не заботитесь о настройке известного один. –

+0

Разве это не цель date_default_timezone_set? – dirk

+0

Не уверен, что вы имеете в виду, если вы выберете 'America/New_York', он будет использовать время в Нью-Йорке, а не UTC. И MySQL - это другая программа, которая иногда запускается на другом компьютере; он не будет заботиться о часовом поясе PHP. –

ответ

0

Вы должны столкнуться следующие ограничения в отношении PHP и MySQL:

  • MySQL не имеет тип столбца, который позволяет хранить местное время с информацией о часовом поясе.

  • PHP не может передавать сложные типы данных (например, DateTime экземпляров) в MySQL, все должно быть сжато, а MySQL не имеет синтаксиса для передачи литерала даты с информацией о часовом поясе.

На практике это не так плохо, как может показаться, потому что вы обычно не нужны местное время пользователя, вставленной информации: вам просто нужно знать точный момент времени, сохраненную дату относится к (и необязательно) часовому поясу, в котором должна отображаться сохраненная дата. И есть в основном три разумных способа сделать это:

  1. Используйте формат, на который не влияют часовые пояса, например. временная метка Unix, хранящаяся как INT.

  2. Используйте тип столбца даты с информацией о часовом поясе, например. a TIMESTAMP (не следует путать с временными метками Unix), где часовой пояс всегда UTC.

  3. Используйте тип столбца даты с информацией о неявном часовом поясе, например. a DATE или DATETIME столбец, в котором вы решили, что все даты относятся к данному часовому поясу, возможно, к UTC.

Разница между # 2 и # 3 заключается в том, знает ли MySQL о часовом поясе, или это то, что знают только вы и ваш код.

Какой бы подход вы выбрали, это необходимо, чтобы все программы, которые, как ожидается, сделать время преобразования зоны проинструктированы о том, что часовой пояс для использования:

  • PHP нужен часовой пояс для создания/отображения Unix временные метки и конвертировать из/в локальное время, набранное/ожидаемое пользователем, и ожидаемое/напечатанное MySQL, например:

    $user_date = new DateTime('2016-10-03 00:00:00', new DateTimeZone('Europe/Berlin')); 
    $user_date->setTimezone(new DateTimeZone('UTC')); 
    echo $user_date->format('c'); 
    
  • MySQL нуждается в часовой пояс, когда вы используете TIMESTAMP столбцы, чтобы конвертировать из/в местное время, например:

    mysql> create table foo(
        -> foo int(10) unsigned auto_increment, 
        -> my_date timestamp, 
        -> primary key (foo) 
        ->); 
    Query OK, 0 rows affected (0.00 sec) 
    
    mysql> set @@time_zone = '+01:00'; 
    Query OK, 0 rows affected (0.00 sec) 
    
    mysql> insert into foo (my_date) values ('2016-12-27 18:50:00'); 
    Query OK, 1 row affected (0.00 sec) 
    
    mysql> set @@time_zone = '-07:00'; 
    Query OK, 0 rows affected (0.00 sec) 
    
    mysql> insert into foo (my_date) values ('2016-12-27 18:50:00'); 
    Query OK, 1 row affected (0.00 sec) 
    
    mysql> select * from foo order by 1; 
    +-----+---------------------+ 
    | foo | my_date    | 
    +-----+---------------------+ 
    | 1 | 2016-12-27 10:50:00 | 
    | 2 | 2016-12-27 18:50:00 | 
    +-----+---------------------+ 
    2 rows in set (0.00 sec) 
    
    mysql> set @@time_zone = '+09:30'; 
    Query OK, 0 rows affected (0.00 sec) 
    
    mysql> select * from foo order by 1; 
    +-----+---------------------+ 
    | foo | my_date    | 
    +-----+---------------------+ 
    | 1 | 2016-12-28 03:20:00 | 
    | 2 | 2016-12-28 11:20:00 | 
    +-----+---------------------+ 
    2 rows in set (0.00 sec)