#!/usr/bin/perl # # author: Matt Sisk, April 2004 # no rights reserved -- do what you want with this use strict; use warnings; use DateTime; use DateTime::TimeZone; my %jan_parm = ( year => 2004, month => 1, day => 1); my %aug_parm = ( year => 2004, month => 7, day => 1); my %jan = run_zones(%jan_parm); my %aug = run_zones(%aug_parm); print "Jan (", scalar keys %jan, " zones):\n"; print_zones(\%jan); print "\nAug (", scalar keys %aug, " zones sans jan):\n"; my %notjan; $notjan{$_} = $aug{$_} foreach grep(!$jan{$_}, keys %aug); print_zones(\%notjan); my @znames = DateTime::TimeZone::all_names; my $j5 = find_5_from_12_30(\%jan_parm, [keys %jan], \@znames); my $a5 = find_5_from_12_30(\%aug_parm, [keys %aug], \@znames); my $jj5 = find_5_from_12_30(\%jan_parm, \@znames, [keys %jan]); my $aa5 = find_5_from_12_30(\%aug_parm, \@znames, [keys %aug]); print_one2many($j5, '2004/01/01 12:30 => 17:00'); print_one2many($a5, '2004/07/01 12:30 => 17:00'); print_many2one($jj5, '2004/01/01 12:30 => 17:00'); print_many2one($aa5, '2004/07/01 12:30 => 17:00'); print '-' x 72, "\n"; printf "%3d for %s %5s -> %s\n", scalar keys %$j5, 'Jan', 'other', 'odd'; printf "%3d for %s %5s -> %s\n", scalar keys %$a5, 'Aug', 'other', 'odd'; printf "%3d for %s %5s -> %s\n", scalar keys %$jj5, 'Jan', 'odd', 'other'; printf "%3d for %s %5s -> %s\n", scalar keys %$aa5, 'Aug', 'odd', 'other'; my %tot; foreach my $h ($j5, $a5, $jj5, $aa5) { foreach (keys %$h) { foreach (keys %{$h->{$_}}) { ++$tot{$_}; } } } print scalar keys %tot, " hits total out of ", scalar @znames, " possibilities.\n"; printf("%.2f%% hit ratio\n", 100*((scalar keys %tot)/(scalar @znames))); exit; ### sub run_zones { my %parms = @_; my %zones; foreach my $name (DateTime::TimeZone::all_names) { my $dt = DateTime->new(%parms, time_zone => $name); next unless $dt->offset % 3600; $zones{$name} = $dt->offset; } %zones; } sub find_5_from_12_30 { my($mparms, $basis, $inspects) = @_; my %found; foreach (@$basis) { my $dt = DateTime->new( %$mparms, hour => 12, minute => 30, time_zone => $_, ); find_5_from_dt($dt, $inspects, \%found); } \%found; } sub find_5_from_dt { my($dt, $inspects, $hits) = @_; foreach my $name (@$inspects) { my $c = $dt->clone; $c->set_time_zone($name); if ($c->hour == 17 && $c->minute == 0) { ++$hits->{$dt->time_zone->name}{$name}; } } } sub print_zones { my $h = shift; my $len = 0; foreach (keys %$h) { $len = length if length > $len; } foreach (sort keys %$h) { printf "%${len}s %3d:%02d\n", $_, int($h->{$_}/3600), int(($h->{$_}%3600)/60); } } sub print_many2one { my($h, $label) = @_; print "\n$label\n", '-' x 72, "\n"; my $len = 0; foreach (keys %$h) { $len = length if length > $len; } foreach (sort keys %$h) { printf "%${len}s => %s\n", $_, join(', ', sort keys %{$h->{$_}}); } } sub print_one2many { my($h, $label) = @_; print "\n$label\n", '-' x 72, "\n"; my $len = 0; foreach (keys %$h) { $len = length if length > $len; } foreach (sort keys %$h) { printf("%${len}s =>\n", $_); foreach (sort keys %{$h->{$_}}) { printf "%${len}s %s\n", ' ', $_; } } }