Eugene van der pijll wrote:
>Jim Monty schreef:
>> I want to iterate the time zones of the world to generate a report of
>> all days that aren't exactly 24 hours. I want to handle
>> America/Caracas and America/Sao_Paulo correctly. You mentioned
>> 2007-12-09 was 24.5 hours long in Venezuela. This is precisely the
>> kind of outlier I'm after.
>
> If you want to handle the Sao Paulo situation correctly, measure the
> intervals between two middays (12:00), instead of between midnights (0:00).
>
> It should show the same non-24 hour days, except when there are two DST
> changes in one day. Which is unlikely, but not impossible, given that
> DST is defined by politicians.
It seems there's no one-size-fits-all workaround for all time zones in all
years.
Here's my first shot at a script. It combines Zefram's suggestion to use
$dt->epoch() and Eugene's recommendation to measure the intervals at noon
instead of at midnight. Next, I'd like to refactor it using...um...I'm not
sure, but something other than $dt->epoch().
#!perl
use strict;
use warnings;
use DateTime;
@ARGV or die "Usage: perl $0 <year> ...\n";
for my $year (@ARGV) {
for my $time_zone (DateTime::TimeZone->all_names()) {
my $today = DateTime->from_day_of_year(
year => $year,
day_of_year => 1,
hour => 12,
time_zone => $time_zone,
);
(my $yesterday = $today->clone())->subtract( days => 1 );
my $hours = ($today->epoch() - $yesterday->epoch()) / 3_600;
my $year_today = $today->year();
while ($year_today == $year) {
(my $tomorrow = $today->clone())->add( days => 1 );
my $date = $today->date();
if ($hours != 23 && $hours != 24 && $hours != 25) {
printf("%-10s %-4s %s\n", $date, $hours, $time_zone);
}
$hours = ($tomorrow->epoch() - $today->epoch()) / 3_600;
$today = $tomorrow;
$year_today = $today->year();
}
}
}
exit 0;
__END__
C:\>perl oddhours.pl 2007
2007-12-09 24.5 America/Caracas
2007-03-11 22 America/Indiana/Winamac
2007-03-25 24.5 Australia/Lord_Howe
2007-10-28 23.5 Australia/Lord_Howe
C:\>
It's easy enough to find stranger and even more problematic dates.
C:\>perl oddhours.pl 1961
1961-01-01 23.7458333333333 Africa/Dar_es_Salaam
1961-08-10 23.5 Asia/Seoul
C:\>perl oddhours.pl 1967
Invalid local time for date in time zone: Africa/Casablanca
C:\>
Since this is my first effort to do something quasi-useful with DateTime using
DateTime math, all feedback, criticisms and suggestions are most welcome.
Jim Monty