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