Мне интересно, как другие люди справляются с этим сценарием.
Что делать, если у вас есть работа, запланированная на 1:30 утра. Осенью, когда время меняется, час с 1:00:00 до 1:59:59 повторяется, и это задание запускается дважды.
Это может быть планировщик задач Windows, агент SQL или любой другой инструмент планирования. Кажется, что большинство этих инструментов основано на машинном времени, а не на времени UTC. Если бы я сказал ему запускать задание по всемирному координированному времени каждую ночь, у меня не было бы проблемы с дублированием часов.
Правильное планирование будущих задач по местному времени с учетом часовых поясов и перехода на летнее время - очень сложная тема. Я уже писал об этом раньше с точки зрения программирования на Stack Overflow. Вот и Вот.
Я резюмирую не с точки зрения программирования:
Определите свои шаблоны повторений с помощью местный время - не UTC. Например, если вы установили ежедневный будильник, который будит вас в 8:00 каждый день, вы не захотите просыпаться на час раньше или на час позже после перехода на летнее время. Если я нахожусь в тихоокеанском часовом поясе США, я не могу запланировать 16:00 по всемирному координированному времени, потому что после перехода необходимо будет переключиться на 15:00 по всемирному координированному времени, чтобы сохранить то же 8:00 по местному времени.
Определите часовой пояс, который представляет «местное» время. Не думайте, что местный часовой пояс сервера совпадает с часовым поясом, который важен для конечного пользователя.
Проект местное время до даты и времени в формате UTC для каждого события, при котором должно запускаться событие.
Вы почти всегда будете делать это для следующего немедленного появления, так что вы можете использовать часы UTC для определения реального момента времени для запуска.
В некоторые случаев, вы можете также спроецировать следующие несколько (или много) экземпляров, например следующие 5 экземпляров, или все экземпляры на следующий год. (Эта часть очень специфична для требований приложения.)
Имейте в наличии стратегию (фиксированную или настраиваемую) того, что делать с событиями, которые выпадают во время летнее время переход:
Для перехода «пружина вперед» существует промежуток отсутствия местного времени, когда событие может не существовать. Например, по тихоокеанскому времени США ежедневная задача, запускаемая в 2:00 утра по местному времени, не будет существовать 9 марта 2014 г. В большинстве случаев вы захотите увеличить это время на сумму экономии (обычно на 1 час. ), так в тот день он будет работать в 3:00, но вернется к работе в 2:00 утра в следующем экземпляре. (Однако вполне возможно, что для этого вам понадобится другая стратегия.)
Для перехода «назад» существует перекрытие дублированного местного времени, когда может существовать событие. дважды. Например, в тихоокеанском времени США ежедневная задача, запускаемая в 1:00, будет иметь два возможных времени, когда она может выполняться 2 ноября 2014 г. В большинстве случаев вы захотите запустить ее в первый наступление 1:00 AM PDT и пропустить следующее появление 1:00 AM PST той же даты. (Но опять же, ты мощь хотите другую стратегию, такую как запуск во втором экземпляре или запуск в обоих. YMMV)
Будьте готовы к пересчитать все время появления в формате UTC, если вам когда-либо понадобится обновить данные о часовом поясе. В IANA / Olson TZDB выпускает несколько обновлений каждый год, потому что правительства мира все время меняют свое мнение о смещении часовых поясов и правилах перехода на летнее время. Вы не можете предполагать в течение какого-то определенного периода времени в будущем, что правила не изменятся..
Обязательно подписаться на анонсы выпусков данных о часовых поясах и иметь процесс их применения в ваших системах и / или приложениях.
В традиционной корпоративной среде это должно быть ответственностью ИТ-отдела. Оперативный персонал.
В зависимости от вашей среды вы можете получать эти данные через tzdata
обновления пакета linux, через Java JRE или tzupdater, или любое количество других каналов. Иногда это зависит от среды, а иногда от конкретной платформы программирования, например Пакет timezonedb PECL для PHP, и многие другие.
У Microsoft есть собственные данные о часовых поясах. В Windows, если вы используете TimeZoneInfo
из .NET (например), вы используете эти данные. Обновления поступают из Вот, а также автоматически отправляются через Центр обновления Windows, поэтому вам следует следить за ними, чтобы знать, когда / если вам нужно пересчитать.
С учетом всего этого является все еще сценарий, в котором вы планируете только по UTC, и это для АБСОЛЮТНЫЙ будущие события. Примеры:
Задание, которое выполняется каждые X часов или каждые X минут.
Время начала и окончания восхода или другое астрономическое явление.
Чувствительное ко времени окно безопасности, например, при передаче конфиденциальной информации другой стороне в заранее оговоренное время.
Windows не обязательно поступает правильно. Обратите внимание на то, как вы определяете триггер:
Если вы установите флажок «Синхронизировать по часовым поясам», задача будет запланирована только по всемирному координированному времени. (Все время по-прежнему отображается как местное время, но хранится как UTC.) Итак, это то, что я ранее назвал «абсолютным» событием.
Если вы не установите этот флажок, он будет использовать местный часовой пояс компьютера, на котором выполняется код. Это не дает вам возможности указать часовой пояс, так что это не очень хорошая реализация ИМХО.
Я не совсем уверен, что это за поведение DST, но я поэкспериментирую и вернусь к вам по этому поводу. Вероятно, он делает то, что я описал выше, но не обязательно.
Планировщик агента SQL еще хуже, поскольку он только позволяет использовать время локального сервера. Опять же, нельзя указать часовые пояса, и вы также не можете указать UTC.
Это было просил, но не принято.
Как вы заметили, час между 1:00 и 2:00 повторяется в конце летнего времени; когда происходит обратное изменение (начало летнего времени), время между 2 и 3 часами ночи не происходит (и ваше задание не запускается). Ваши лучшие варианты будут
Как правило, наплевать.
Задайте вопрос "а что, если задача выполняется дважды?"
Как правило, это не имеет значения, поэтому ничего делать не нужно. Если это имеет значение, самое простое решение - перенести работу в нерабочее время, на которое влияет переход на летнее время.