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
lmpx.com only provides a reader for public news (NNTP) servers. It is not
affiliated with the servers or forums shown here and is not responsible for
the content of articles, which is written by their respective authors.