Я храню события в своей базе данных. У меня есть время начала и окончания, «tickets_start» и «tickets_end» (когда продажа билетов фактически начинается / заканчивается – в отличие от начала / конца фактического события).
До сих пор я создал методы, которые делают все забавные вещи, такие как преобразование даты / времени в GMT перед сохранением, а затем обратно в соответствующий часовой пояс для отображения.
Я храню часовой пояс в поле varchar со значениями, такими как «America / New_York».
Но теперь мне нужно начать работать, если пользователь хочет разрешить повторять события. Я делал это раньше, и дело не в этом, но не в нескольких часовых поясах.
Сначала я подумал, что это было бы неважно, но потом понял, что если начальная дата начала была в июле (как пример), и она повторяется каждый месяц в течение года, в какой-то момент, Daylight Savings Time сделает это так что переход от GMT изменит время по-другому. Один месяц, при конвертации 12:00, он изменил бы его на -5, а следующий, он изменил бы его на -4 из-за DST.
Моя нынешняя мысль заключается в том, что я буду хранить «dst» tinyint (1) для того, были ли введены даты начала / окончания во время DST, а затем сделать способ изменить время на час, если / когда это необходимо.
Но – подумал, что я спрошу здесь, надеюсь, может быть, есть «нормальный» для этого или легкий, о котором я не думаю.
(cakephp 2.4.x)
Во-первых, примите к сведению, что в современной терминологии вы должны указывать UTC вместо GMT. Они в основном эквивалентны, за исключением того, что UTC более точно определен. Зарезервируйте термин GMT для обозначения части часового пояса в Соединенном Королевстве, которая действует в течение зимних месяцев, имеющих смещение UTC + 0.
Теперь на ваш вопрос. UTC не всегда является лучшим способом хранения всех значений даты и времени. Он работает особенно хорошо для прошлых событий или для будущих абсолютных событий, но он не работает так хорошо для будущих местных событий, особенно в будущих повторяющихся событиях.
Я недавно написал об этом в другом ответе , и это один из немногих исключений, когда местное время имеет больше смысла, чем UTC. Главный аргумент – «проблема с будильником». Если вы установите будильник по UTC, вы будете просыпаться час раньше или поздно в день перехода DST. Вот почему большинство людей устанавливают свои будильники по местному времени.
Конечно, вы не можете просто сохранить местное время, если работаете с данными со всего мира. Вы должны хранить несколько разных вещей:
За последние два, понять, что UTC эквивалент любой локальной даты / времени может измениться, если правительство, ответственное за этот часовой пояс, решает что-то изменить. Поскольку каждый год обновляется несколько обновлений базы данных часовых поясов, вам нужно будет запланировать подписку на объявления об обновлениях и регулярно обновлять свою базу данных часовых поясов. Всякий раз, когда вы обновляете данные о часовом поясе, вам необходимо пересчитать эквивалентные времена UTC для всех будущих событий.
Наличие эквивалентов UTC важно, если вы планируете показывать список событий, охватывающий более одного часового пояса. Это те значения, которые вы запросите для создания этого списка.
Еще один момент, который следует учитывать, заключается в том, что если событие запланировано на локальное время, которое происходит во время перехода на летнее время DST, вам нужно будет решить, произойдет ли событие в первом экземпляре (обычно) или втором экземпляре (иногда) или оба (реже), и встроить в ваше приложение механизм для обеспечения того, чтобы событие не срабатывало дважды, если вы этого не хотите.
Если вы искали простой ответ – извините, но его нет. Планирование будущих событий в часовых поясах – сложная задача.
У меня было несколько человек, которые показали мне технику, в которой они используют время UTC для планирования, то есть они выбирают дату начала в локальное время, конвертируют ее в UTC, чтобы сохранить и хранить идентификатор часового пояса. Затем во время выполнения они применяют часовой пояс, чтобы преобразовать исходное время UTC в локальное время, а затем использовать это локальное время для вычисления других повторений, как если бы они были первоначально сохранены, как указано выше.
Хотя этот метод будет работать , недостатки:
Если есть обновление часового пояса, которое изменяет местное время до запуска первого экземпляра, оно отключит весь график. Это можно смягчить, выбрав время в прошлом для «первого» экземпляра, так что второй экземпляр действительно является первым.
Если время действительно является «плавающим» временем, которое должно следовать за пользователем (например, в будильнике на сотовом телефоне), вам все равно придется хранить информацию о часовом поясе для зоны, в которой она была первоначально создана, даже если это не та зона, в которой вы хотите работать.
Это добавляет дополнительную сложность без какой-либо выгоды. Я бы зарезервировал этот метод для ситуаций, когда у вас, возможно, был планировщик только для UTC, который вы пытаетесь модифицировать поддержку часового пояса.