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

PHP и MySQL: преобразование сохраненного TIMESTAMP в пользовательскую локальную часовую зону

Итак, у меня есть сайт с функцией комментариев, где временная метка комментария хранится в базе данных MySQL. Насколько я понимаю, временная метка преобразуется в UTC при сохранении, а затем возвращается обратно в часовой пояс по умолчанию при восстановлении. В моем случае мой сервер находится в часовом поясе Central Daylight Time (CDT).

У меня есть план, чтобы получить часовой пояс от каждого пользователя через форму ввода. Я просто хотел узнать, как преобразовать значение TIMESTAMP в пользовательский часовой пояс.

  • Во-первых, я бы конвертировал из UTC в локальный часовой пояс? Или CDT в локальный часовой пояс?
  • Во-вторых, как я буду делать это на PHP? Я бы просто сделал:
$userTimezone = new DateTimeZone($userSubmittedTimezoneString);
$myDateTime = new DateTime($storedTimestamp, $userTimezone);

... или это неверно?

4b9b3361

Ответ 1

Значения Date/time/datetime хранятся в MySQL по мере их поставки. То есть если вы INSERT строка 2012-04-17 12:03:23 в столбец DATETIME, то значение, которое будет сохранено. Он будет преобразован внутренне в метку времени, которая может быть или не быть точным (см. Ниже), но когда вы снова запрашиваете значение, вы получите то же самое значение; кругооборот прозрачен.

Проблемы могут возникнуть, если вы попытаетесь выполнить вычисления времени внутри SQL. То есть любая операция, требующая SQL для учета часового пояса и/или времени сервера. Например, используя NOW(). Для любой из этих операций время часового пояса и/или время сервера должны быть установлены правильно. См. Проблемы с часовым поясом.

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

date_default_timezone_set('Asia/Tokyo'); // your reference timezone here

$date = date('Y-m-d H:i:s');

/* INSERT $date INTO database */;

$date = /* SELECT date FROM database */;

$usersTimezone = new DateTimeZone('America/Vancouver');
$l10nDate = new DateTime($date);
$l10nDate->setTimeZone($usersTimezone);
echo $l10nDate->format('Y-m-d H:i:s');

Ответ 2

Нет надежного способа получить часовой пояс пользователя. Информация о часовом поясе не отправляется в заголовках HTTP. Лучшее, что вы можете сделать, это либо:

  • Сопоставление IP-адреса с географической базой данных -или -
  • Используйте Javascript для получения времени, установленного на компьютере пользователя, и отправьте его на сервер (AJAX) или введите временную строку на клиенте.

Ответ 3

$timezone = new DateTimeZone('America/Vancouver');

$date = new DateTime(date('m/d/Y h:i:s a', time()));
$date->setTimeZone($timezone);
echo $date->format('l F j Y g:i:s A')."\n";

Замените new DateTime(date('m/d/Y h:i:s a', time())); на new DateTime("UTC Time");

Вы можете создать новый объект DateTimeZone() для каждого пользовательского ввода.

Ответ 4

Способ сделать это с помощью javascript. Я думаю, что лучший способ сделать это - сохранить пользователей GMT в своих файлах cookie и получить их в форме процесса PHP.

<script language="javascript">

function TimeZoneCookie()
{
 var u_gmt = (-(new Date().getTimezoneOffset()))/60;
 var o_date = new Date("December 31, 2025");
 var v_cookie_date = o_date.toGMTString();
 var str_cookie = "utimezone="+u_gmt;
 str_cookie += ";expires=" + v_cookie_date;
 document.cookie=str_cookie;
}
//---------------------
TimeZoneCookie();

</script>

u_gmt:

  • Date().getTimezoneOffset() возвращает смещение в GMT-0 в минутах
  • Так как getTimezoneOffset() вернет смещение в GMT-0, а не из GMT-0, нам нужно будет повернуть его. Как? просто, зная, что -*-=+ и -*+=-. Если вы знаете основную математику, вы уже знаете этот принцип.
  • Как я сказал в шаге 1, getTimezoneOffset() вернет смещение в минутах, поэтому мы просто разделим его на 60, чтобы мы могли получить формат смещения gmt.

Результат: (-(new Date().getTimezoneOffset()))/60


Теперь извлеките файл cookie в PHP:

<?php

$user_timezone = $_COOKIE['utimezone'];

?>