Настройки веб-сервера и базы данных, чтобы получить часовой пояс UTC «правильно»,

Я перегружен, пытаясь понять это: у нас есть серверы, расположенные в дюжине часовых поясов, с Apache и MySQL, работающими на всех или некоторых из них, а также MySQL, размещенный на Amazon RDS.

Я хочу знать «Лучшая практика» или как настраивать каждую установку MySQL и PHP, чтобы при добавлении строки в базу данных из PHP я уверен, что на самом деле существует время UTC, когда произошло событие, независимо от того, где находится сервер, когда это произошло. Представление его пользователю в любой момент времени не является проблемой – я просто хочу знать, что столбцы datetime фактически сохраняют фактический момент времени, когда что-то произошло.

Как и сейчас, веб-серверы настроены на то, что локальный часовой пояс происходит из-за запланированных событий и т. Д., И я не уверен, какие части головоломки используют настройки, из которых можно найти все, что записано в базе данных ,

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

Если вы ограничиваетесь типами MySQL DATE и DATETIME, вы можете в значительной степени игнорировать проблемы с часовым поясом в самой MySQL. Вы хотите избежать типа TIMESTAMP MySQL, потому что:

MySQL преобразует значения TIMESTAMP из текущего часового пояса в UTC для хранения и обратно из UTC в текущий часовой пояс для извлечения. (Этого не происходит для других типов, таких как DATETIME.) По умолчанию текущий часовой пояс для каждого соединения – это время сервера.

https://dev.mysql.com/doc/refman/5.7/en/datetime.html

Что касается чтения / записи значений DATETIME, вы получите именно то, что вы положили, что хорошо.

Это оставляет вам проблему всегда обеспечивать, чтобы вы записывали значения UTC в базу данных.

Лучший способ гарантировать, что PHP использует UTC, – явно указать его в приложении с помощью date_default_timezone_set () . Это гарантирует, что вызовы типа date('Ymd H:i:s') дадут вам значение UTC. Он также гарантирует, что что-то вроде (new \DateTime('now'))->getTimezone() вернет экземпляр UTC \ DateTimeZone.

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

 /** @var \DateTimeZone $userTZ */ $userTz = getUserTimezone(); $dateTime = new \DateTime($user_submitted_date_string, $userTz); $dateTime->setTimezone(new \DateTime('UTC')); $dateTimeStr = $dateTime->format('Ymd H:i:s'); 

Достаточно просто, всегда храните unix- время в базе данных (или если вы хотите получить микросекундную точность с помощью microtime). Затем, независимо от часового пояса каждого из ваших веб-серверов, если два из них получают запрос одновременно, это будет одно и то же целочисленное значение, которое сохраняется в базе данных (поле базы данных shoudl, очевидно, является int (или большим int для микро время))

И как отобразить? Легко с javascript.

 new Date(unix_timestamp); 

Это дает дату и время в часовом поясе пользователя.