Как мне определить следующий переход на летнее время (DST) для часового пояса в Perl?

Я работаю над веб-приложением World Clock, и я хотел бы добавить функцию, чтобы отмечать, как и когда каждая локация в следующий раз подвергнется DST-изменению.

Я использую DateTime а также DateTime::Timezone Модули CPAN, которые, кажется, обеспечивают все мыслимые функции, кроме этой! DateTime::Timezone является реализацией базы данных tz/Olson.

Пока я сравниваю локальное смещение с UTC, как сейчас, так и на 24 часа вперед, что позволяет мне отмечать, что это за эффект, но не точно, когда он происходит.

Мое доказательство концепции вычисляет это каждую минуту. Я думаю, что следующий шаг:

  • Создайте таблицу поиска с использованием аналогичного метода для следующих 365 дней, чтобы определить затронутые дни, а затем посмотрите на каждый час в эти дни.

  • как-то разобрать правила DST в DateTime::Timezone модуль.

Есть идеи? Должен отметить, что мои знания Perl довольно просты.


Редактировать:

Похоже, что другой вариант может быть, чтобы портировать на PHP и использовать DateTimeZone::getTransitions, Это вернуло массив всех переходов, но PHP 5.3.0 просто добавил опционально timestamp_begin а также timestamp_end параметры, чтобы ограничить диапазон.

2 ответа

Решение

Недокументированный атрибут _rules из DateTime::TimeZone объект дает вам массив DateTime::TimeZone::OlsonDB::Rule объекты. Они кодируют начало и конец соблюдения.

my $o = DateTime::TimeZone->new(name => 'Europe/Vienna')->_rules->[1];
say sprintf "%s summertime ends at %s on %s in %s each year", $o->name, $o->at, $o->on, $o->month;

Я советую вам подать сообщение об ошибке, чтобы запросить обнародование и документирование этого API, чтобы ваш код мог положиться на него, и он будет должным образом поддерживаться сопровождающими DT.

Вы можете использовать базу данных tz

"База данных часовых поясов общего пользования содержит код и данные, которые представляют историю местного времени для многих репрезентативных местоположений по всему миру. Она периодически обновляется, чтобы отражать изменения, внесенные политическими органами в границы часовых поясов, смещения UTC и переход на летнее время правила ".

Для этого есть даже модуль perl. "DateTime::TimeZone содержит скрипт parse_olson, который компилирует источник tz в модули Perl. Он является частью проекта Perl DateTime, который свободно доступен как по лицензии GPL, так и по лицензии Perl Artistic. DateTime::TimeZone также содержит скрипт tests_from_zdump, который генерирует тестовые случаи для каждого тактового перехода в базе данных tz. "

Как вы уже сказали, вы уже используете этот модуль, но похоже, что вы не используете все его функции. Я не уверен, какая часть кода tz предоставляется через модуль DateTime:: TimeZone. В этом случае вам может быть лучше назвать это. Существует ряд веб-сервисов, уже использующих базу данных tz, поэтому она хорошо используется.

Вам, вероятно, следует написать скрипт на perl или shell для периодической загрузки источника базы данных tz, чтобы поддерживать правила в актуальном состоянии.

Другие вопросы по тегам