Подтвердить что ты не робот

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

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

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

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

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

4b9b3361

Ответ 1

MySQL: UTC_TIMESTAMP()

Возвращает текущую дату и время UTC как значение в "ГГГГ-ММ-ДД ЧЧ: ММ: СС" или YYYYMMDDHHMMSS.uuuuuu формат, в зависимости от того, является ли функция используется в строковом или числовом контексте

PHP: gmdate()

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

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

Ответ 2

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

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

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

<?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, 'Y-m-d H:i:s');
}
?>

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

Ответ 3

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

Ответ 4

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)

Ответ 5

Как говорит Халлук, вы можете сохранить дату в формате UTC datetime. Я дополняю его ответ на ситуации, когда дата, которую вы хотите вставить, приходит из кода 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("Y-m-d 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("Y-m-d H:i:s") дает текущую дату в таком формате. В любом случае все, что вам нужно сделать, это построить строку, представляющую дату, которую вы хотите вставить в UTC.

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

Ответ 6

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

MySQL 5.7 +