Всюду, где я читал о времени преобразования в часовой пояс пользователя, говорится, что лучшим способом является сохранение даты и времени в 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+