Я застрял на этом два дня и не получил нигде. Я склонен думать о будущем и о будущих проблемах, которые будут возникать. Время моего сервера настроено на UTC, а linux box полностью обновляется с помощью часовых поясов, а данные находятся в моей базе данных.
Я объясню свою систему для лучшего ответа.
Этот сайт продает "предметы", но может продаваться только в открытые и закрытые сроки. В магазинах могут быть часы сплит: т.е. Открыт с 8 до 12 часов 1 вечера 8 вечера... и т.д.
Итак, моя таблица часов выглядит так:
id (1) | store_id (1) | opens (08:00) | closes (21:00)
Выше приведен пример данных рядом с именем столбца. В принципе, идентификатор № 1 может находиться в Лос-Анджелесе (США/Тихоокеанский регион), или он может находиться в Нью-Йорке (США/восток).
Каков наилучший способ гарантировать, что я не пропущу час простоя, поэтому я могу отключить пользователей для заказа из этих магазинов в нерабочее время. Если я отключусь от одного часа, то один час никто не может заказать, когда они действительно открыты, и час пользователи закажут, когда они действительно закрыты. Visa versa в зависимости от изменения времени.
Кто-нибудь справился с этим? И если да, то как вы это сделали?
Каков наилучший способ решить эту проблему. Я занимался этим, и он ел мой мозг в течение последних 48 часов.
Пожалуйста, помогите!:)
На самом деле это очень легко добиться в Postgres и MySQL. Все, что вам нужно сделать, это сохранить часовой пояс в пользовательской части, установить сервер TZ в UTC, а затем преобразовать между ними.
Пример:
SELECT
CASE WHEN (
(CAST((CURRENT_TIMESTAMP at time zone s.timezone) as time) BETWEEN h.opens AND h.closes) AND
h.day = extract(dow from CURRENT_TIMESTAMP at time zone s.timezone)) THEN 0 ELSE 1 END
) as closed
FROM store s
LEFT JOIN store_hours r ON s.id = r.store_id
HERE h.day = extract(dow from CURRENT_TIMESTAMP at time zone s.timezone)
Это что-то вроде этого. Я должен был делать typginging таким образом, потому что я был ограничен для использования Doctrine 1.2.
Работает как шарм даже с изменениями DST.
Одно дело иметь в виду, что некоторые места (думаю, Аризона) не делают DST. Вы можете захотеть убедиться, что ваша база данных имеет достаточно информации, чтобы вы могли различать LA и Phoenix, если это окажется необходимым.
Предполагая, что вы следуете советам ITroubs и устанавливаете смещения в базе данных (и, возможно, информацию о том, хранится ли хранилище в локали DST), вы можете сделать следующее:
Создайте свой код, чтобы он проверял, действует ли DST, и строит ваши запросы соответствующим образом. Если все ваши магазины находятся в Нью-Йорке и Лос-Анджелесе, тогда вы можете просто добавить 1 к смещению, когда это необходимо. Если нет, вам понадобится запрос, который использует разные правила для хранилищ DST и не-DST. Что-то вроде,
SELECT store_id
FROM hours
WHERE
(supportsDST = true AND opens < dstAdjustedNow AND closes > dstAdjustedNow)
OR (supportsDST = false AND opens < UTCNow AND closes > UTCNow)
Если вы идете по этому маршруту, я рекомендую как можно больше централизовать и изолировать код, который имеет дело с этим.
Кроме того, вы не упомянули об этом, но я предполагаю, что хранилище с разделенным временем будет иметь две строки в таблице часов, по одному для каждого открываемого блока.