PHP синхронизирует часовой пояс с переходом на летнее время

У меня есть веб-сайт, который загружает данные в таблицу MySQL. Две записи в таблице — «дата начала» и «дата окончания». «дата начала» устанавливается автоматически с использованием CURRENT_TIMESTAMP. «конечная дата» выбирается пользователем с помощью средства выбора даты.

Это создает проблему, если пользователь находится в другом часовом поясе, чем сервер. Например (я в Тихоокеанском часовом поясе, сервер в Центральном). Если я создам запись в 17:00 и выберу дату окончания 22:00, она попадет в базу данных как 19:00 и 22:00, создав трехчасовое окно вместо 5. Что я хочу, так это преобразовать дату окончания в центральное время (то же самое). как сервер). Итак, используя мой пример, я бы хотел, чтобы записи в базе данных были в 7 часов вечера и в 12 часов ночи.

Я могу получить смещение часового пояса пользователей с помощью этого javascript:

var d = new Date();
var timezone = -d.getTimezoneOffset()/60;

Это возвращает -7 (я нахожусь в GMT-8, я предполагаю, что разница в 1 час связана с переходом на летнее время). Моя первая мысль для решения состоит в том, чтобы предположить, что сервер находится в -5, и сравнить два (возвращаясь к моему примеру, -5 - -7 = 2, поэтому добавьте 2 к «конечной дате»).

Проблема возникает, когда мы переключаемся обратно на стандартное время. Я предполагаю, что мой javascript начнет возвращать -8 вместо -7, нарушая мою функцию. Я знаю о PHP date_default_timezone_get(), но он возвращает строку вместо числа. Я предполагаю, что мне нужна аналогичная функция, которая (для центрального времени) возвращала бы -5 во время летнего времени и -6 в стандартное время.


person user617123    schedule 31.08.2011    source источник
comment
Разве вы не можете получить все соответствующие даты в формате UTC?   -  person Kerrek SB    schedule 31.08.2011
comment
Если вы используете поле mysql timestamp, то все должно быть в порядке. Просто укажите правильный часовой пояс клиента в начале сеанса mysql.   -  person zerkms    schedule 31.08.2011
comment
Я использую метку времени только для «даты начала», которая всегда является центральным временем. «enddate» происходит из средства выбора даты, которое основано на местном времени пользователя. Мне нужен способ преобразовать местное время пользователя в центральное время.   -  person user617123    schedule 31.08.2011
comment
@zerkms Я не хочу, чтобы все даты в базе данных были центральным временем. Другими словами, мне нужно преобразовать местное время пользователя в центральное время, а не наоборот.   -  person user617123    schedule 31.08.2011
comment
@ user617123: вам не нужно этого хотеть. Часовой пояс - это только презентация. Поэтому сохраните его в timestamp и преобразуйте в определенный часовой пояс на этапе вывода.   -  person zerkms    schedule 31.08.2011
comment
@Kerrek SB: Спасибо! Я сначала не понял, что ты имеешь в виду. Я использовал MySQL UTC_TIMESTAMP вместо CURRENT_TIMESTAMP. Затем я использую свою функцию Javascript, чтобы также преобразовать «конечную дату» в UTC. Теперь каждая запись в базе данных однородна. Идеально.   -  person user617123    schedule 31.08.2011
comment
@zerkms: Может быть, я что-то упускаю, но я подумал, что если я укажу часовой пояс клиента в MySQL, а затем использую CURRENT_TIMESTAMP, разные записи от разных пользователей будут основаны на разном времени. Например, два пользователя могут создать запись в одно и то же время, но один укажет 14:00, а другой — 15:00, потому что они находятся в разных часовых поясах. Я хотел, чтобы все было однородным.   -  person user617123    schedule 31.08.2011
comment
@ user617123: нет, mysql хранит значения полей timestamp в формате UTC и конвертирует из/в часовой пояс пользователя. Поэтому не имеет значения, какое местное время пользователя - если вы указали правильный часовой пояс пользователя - в поле будет храниться действительное время UTC.   -  person zerkms    schedule 31.08.2011
comment
@zerkms: Хммм... Я попробовал твой метод. Я попытался установить дату начала и дату окончания на текущее время. Я использовал:   -  person user617123    schedule 31.08.2011
comment
...set time_zone = '-7:00'; insert into mydb.mytable ('startdate', 'enddate') values (current_timestamp, '2011-08-31 11:48:00); и записи в базе данных оказались 13:48:15 и 11:48:00. Они не совпадают.   -  person user617123    schedule 31.08.2011
comment
@ user617123: тогда ты где-то ошибся. Этот метод работает.   -  person zerkms    schedule 01.09.2011


Ответы (2)


Используйте поле временной метки mysql.

Или сохранить все данные в UTC, а потом сделать то, что нужно после в php.

person carlgcode    schedule 31.08.2011

Использование MySQL UTC_TIMESTAMP вместо CURRENT_TIMESTAMP преобразует «дату начала» во время UTC. Мой код JavaScript:

var d = new Date();
var timezone = -d.getTimezoneOffset()/60;

Может использоваться для преобразования конечной даты во время UTC. Теперь все в UTC и совпадает.

person user617123    schedule 31.08.2011