Хранение datetime как UTC в PHP / MySQL

Всюду, где я читал о времени преобразования в часовой пояс пользователя, говорится, что лучшим способом является сохранение даты и времени в UTC, а затем просто добавление смещения часового пояса пользователя к этому времени.

Как сохранить дату в UTC? Я использую поле MySQL DATETIME.

При добавлении новой записи в MySQL в моем PHP-коде я бы использовал now() для вставки в MySQL DATETIME.

Должен ли я использовать что-то другое, чем now() для хранения времени UTC?

MySQL: UTC_TIMESTAMP()

Возвращает текущую дату и время UTC как значение в формате «YYYY-MM-DD HH: MM: SS» или YYYYMMDDHHMMSS.uuuuuu, в зависимости от того, используется ли эта функция в строковом или числовом контексте

PHP: gmdate()

Кроме того, PHP date_default_timezone_set() используется в PHP для установки текущего часового пояса для скрипта. Вы можете установить его в часовой пояс клиента, чтобы все функции форматирования вернули время в свое местное время.

На самом деле, хотя мне было трудно заставить это работать и всегда натыкаться на некоторые из них. Например. временная информация, возвращаемая из MySQL, не отформатирована как «UTC», поэтому strtotime преобразует ее в локальное время, если вы не будете осторожны. Мне любопытно узнать, есть ли у кого-то надежное решение этой проблемы, которое не прерывается, когда даты пересекают границы медиа (HTTP-> PHP-> MySQL и MySQL-> PHP-> HTTP), также рассматривая XML и RSS /Атом.

Я бы предложил ввести дату в часовой пояс UTC. Это сэкономит вам много головных болей в будущем с проблемами летнего времени.

 INSERT INTO abc_table (registrationtime) VALUES (UTC_TIMESTAMP()) 

Когда я запрашиваю данные, я использую следующий скрипт PHP:

 <?php while($row = mysql_fetch_array($registration)) { $dt_obj = new DateTime($row['message_sent_timestamp'] ." UTC"); $dt_obj->setTimezone(new DateTimeZone('Europe/Istanbul')); echo $formatted_date_long=date_format($dt_obj, 'Ymd H:i:s'); } ?> 

Вы можете заменить значение DateTimeZone одним из доступных временных часовых поясов PHP .

NOW() дает вам время (включая смещение часового пояса) системы, запускающей вашу базу данных. Чтобы получить дату / время UTC, вы должны использовать UTC_TIMESTAMP() как описано в Справочном руководстве по MySQL .

https://dba.stackexchange.com/questions/20217/mysql-set-utc-time-as-default-timestamp

Цитируя весь ответ по ссылке выше в случае удаления:

Чтобы согласиться с комментарием @ ypercube, что CURRENT_TIMESTAMP хранится как UTC, но в качестве текущего часового пояса вы можете повлиять на настройку часового пояса вашего сервера с помощью опции -default_time_zone для извлечения. Это позволяет всегда выполнять поиск в формате UTC.

По умолчанию опция «СИСТЕМА» – это то, как установлен часовой пояс вашей системы (который может быть или не быть UTC!):

 mysql> SELECT @@global.time_zone, @@session.time_zone; +--------------------+---------------------+ | @@global.time_zone | @@session.time_zone | +--------------------+---------------------+ | SYSTEM | SYSTEM | +--------------------+---------------------+ 1 row in set (0.00 sec) mysql> SELECT CURRENT_TIMESTAMP(); +---------------------+ | CURRENT_TIMESTAMP() | +---------------------+ | 2012-09-25 16:28:45 | +---------------------+ 1 row in set (0.00 sec) 

Вы можете установить это динамически:

 mysql> SET @@session.time_zone='+00:00'; Query OK, 0 rows affected (0.00 sec) mysql> SELECT @@global.time_zone, @@session.time_zone; +--------------------+---------------------+ | @@global.time_zone | @@session.time_zone | +--------------------+---------------------+ | SYSTEM | +00:00 | +--------------------+---------------------+ 1 row in set (0.00 sec) 

Или навсегда в my.cnf:

 [mysqld] **other variables** default_time_zone='+00:00' 

Перезагрузите сервер, и вы увидите изменение:

 mysql> SELECT @@global.time_zone, @@session.time_zone; +--------------------+---------------------+ | @@global.time_zone | @@session.time_zone | +--------------------+---------------------+ | +00:00 | +00:00 | +--------------------+---------------------+ 1 row in set (0.00 sec) mysql> SELECT CURRENT_TIMESTAMP(); +---------------------+ | CURRENT_TIMESTAMP() | +---------------------+ | 2012-09-25 20:27:50 | +---------------------+ 1 row in set (0.01 sec) 

Как говорит Халлук, вы можете сохранить дату как дату и время UTC. Я дополняю его ответ на ситуации, когда дата, которую вы хотите вставить, поступает из кода PHP и добавляет некоторые сведения о том, как она работает:

 $pdo = new PDO('mysql:host=mydbname.mysql.db;dbname=mydbname', 'myusername', 'mypassword'); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $insertStmt = $pdo->prepare("insert into test (last_modified)" ." values(:last_modified)"); $insertStmt->bindParam(':last_modified', $lastModified, PDO::PARAM_STR); $lastModified = gmdate("Ymd H:i:s"); $insertStmt->execute(); 

Фактически datetime в PHP не имеет связанного с ним часового пояса. То, что передано PDO, представляет собой просто строку в одном из форматов, распознаваемых MySQL, и представляет дату в часовой пояс UTC. Например, если дата 2015-10-21 19:32:33 UTC+2:00 , приведенный выше код просто говорит MySQL вставить 2015-10-21 17:32:33 . gmtdate("Ymd H:i:s") дает вам текущую дату в таком формате. В любом случае все, что вам нужно сделать, это построить строку, представляющую дату, которую вы хотите вставить в UTC.

Затем, когда вы читаете дату, вы должны сообщить PHP, что часовой пояс даты, которую вы только что получили, – UTC. Используйте код в ответе Халука для этого.

Random: UTC_TIMESTAMP (6) для времени с 6 цифрами микросекунд.

MySQL 5.7+