Я перегружен, пытаясь понять это: у нас есть серверы, расположенные в дюжине часовых поясов, с Apache и MySQL, работающими на всех или некоторых из них, а также MySQL, размещенный на Amazon RDS.
Я хочу знать «Лучшая практика» или как настраивать каждую установку MySQL и PHP, чтобы при добавлении строки в базу данных из PHP я уверен, что на самом деле существует время UTC, когда произошло событие, независимо от того, где находится сервер, когда это произошло. Представление его пользователю в любой момент времени не является проблемой – я просто хочу знать, что столбцы datetime фактически сохраняют фактический момент времени, когда что-то произошло.
Как и сейчас, веб-серверы настроены на то, что локальный часовой пояс происходит из-за запланированных событий и т. Д., И я не уверен, какие части головоломки используют настройки, из которых можно найти все, что записано в базе данных ,
Прошу прощения, если вопрос кажется неясным, на данный момент я не знаю, чего не знаю, поэтому получить точный вопрос даже сложно. Кроме того, все наши даты указаны в базе данных как поля DateTime, поэтому сохранение временных меток невозможно.
Если вы ограничиваетесь типами MySQL DATE и DATETIME, вы можете в значительной степени игнорировать проблемы с часовым поясом в самой MySQL. Вы хотите избежать типа TIMESTAMP MySQL, потому что:
MySQL преобразует значения TIMESTAMP из текущего часового пояса в UTC для хранения и обратно из UTC в текущий часовой пояс для извлечения. (Этого не происходит для других типов, таких как DATETIME.) По умолчанию текущий часовой пояс для каждого соединения – это время сервера.
Что касается чтения / записи значений 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);
Это дает дату и время в часовом поясе пользователя.