Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How should I determine next daylight saving time (DST) transition for a timezone in Perl?

I'm working on a world clock web application, and I'd like to add a function to note how and when each location will next undergo a DST change.

I'm using the DateTime and DateTime::Timezone CPAN modules, which seem to provide every conceivable function apart from this one! DateTime::Timezone is an implementation of the tz/Olson database.

So far, I'm comparing local offset to UTC, both now and 24 hours ahead, which allows me to flag what the effect is but not exactly when it occurs.

My proof of concept calculates this every minute. I'm thinking the next step is either:

  • create a lookup table using a similar method for the next 365 days to identify affected days, then look at each hour within those days

  • somehow parse the DST rules in the DateTime::Timezone module.

Any ideas? I should note that my knowledge of Perl is pretty basic.


Edit:

Looks like another option might be to port to PHP and use DateTimeZone::getTransitions. This did return an array of all transitions, but PHP 5.3.0 just added optional timestamp_begin and timestamp_end paramaters to limit to a range.

like image 713
e100 Avatar asked Jul 14 '10 12:07

e100


2 Answers

The undocumented attribute _rules of an DateTime::TimeZone object gives you an array of DateTime::TimeZone::OlsonDB::Rule objects. These encode the start and end of observances.

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;

I advise you to file a bug to request that this API is made public and documented, so that your code can rely on it and it is going to be supported by the DT maintainers properly.

like image 169
daxim Avatar answered Oct 07 '22 05:10

daxim


You can use the tz database

"The public-domain time zone database contains code and data that represent the history of local time for many representative locations around the globe. It is updated periodically to reflect changes made by political bodies to time zone boundaries, UTC offsets, and daylight-saving rules."

There is even a perl module for it. "DateTime::TimeZone contains a script parse_olson that compiles tz source into Perl modules. It is part of the Perl DateTime Project, which is freely available under both the GPL and the Perl Artistic License. DateTime::TimeZone also contains a script tests_from_zdump that generates test cases for each clock transition in the tz database."

As you have said, you are already using this module, but it sounds like you're not using all it's features. I'm not sure how much of the tz code is exposed via the DateTime::TimeZone module. In which case you might be better off calling it. There are a number of web services already using the tz database so it's well used.

You probably should write a perl or shell script to download the tz database source periodically in order to keep the rules up to date.

like image 31
hookenz Avatar answered Oct 07 '22 06:10

hookenz