#!/usr/bin/perl -l use strict; use warnings; my @initial; use DateTime; use Env::C; use POSIX "mktime"; use Semaphore::SmokeSignals 'LightUp'; sub convert_timezone_datetime { my ($y,$mo,$d,$h,$m,$s,$tz,$new_tz) = @_; my $dt = DateTime->new(year=>$y, month=>$mo, day=>$d, hour=>$h, minute=>$m, second=>$s,time_zone=>$tz); $dt->set_time_zone($new_tz); return map $dt->$_, qw/year month day hour minute second/; } sub convert_timezone_env_c { my ($y,$mo,$d,$h,$m,$s,$tz,$new_tz) = @_; my $save_tz = Env::C::getenv("TZ"); Env::C::setenv("TZ",$tz,1); my $time = POSIX::mktime($s,$m,$h,$d,$mo-1,$y-1900,0,0,-1); Env::C::setenv("TZ",$new_tz,1); POSIX::tzset(); # localtime_r bug ($s,$m,$h,$d,$mo,$y) = localtime($time); $mo++; $y+=1900; # this belongs in a destructor if (defined $save_tz) { Env::C::setenv("TZ",$save_tz,1) } else { Env::C::unsetenv("TZ") } return ($y,$mo,$d,$h,$m,$s); } { my $pipe= LightUp(); sub convert_timezone_env_c_semaphore { my ($y,$mo,$d,$h,$m,$s,$tz,$new_tz) = @_; my $puff= $pipe->Puff(); my $save_tz = Env::C::getenv("TZ"); Env::C::setenv("TZ",$tz,1); my $time = POSIX::mktime($s,$m,$h,$d,$mo-1,$y-1900,0,0,-1); Env::C::setenv("TZ",$new_tz,1); POSIX::tzset(); # localtime_r bug ($s,$m,$h,$d,$mo,$y) = localtime($time); $mo++; $y+=1900; # this belongs in a destructor if (defined $save_tz) { Env::C::setenv("TZ",$save_tz,1) } else { Env::C::unsetenv("TZ") } return ($y,$mo,$d,$h,$m,$s); } } sub convert_timezone_system { my ($y,$mo,$d,$h,$m,$s,$tz,$new_tz) = @_; local $ENV{"TZ"} = $tz; my $time = POSIX::mktime($s,$m,$h,$d,$mo-1,$y-1900,0,0,-1); $ENV{"TZ"} = $new_tz; POSIX::tzset(); # localtime_r bug ($s,$m,$h,$d,$mo,$y) = localtime($time); $mo++; $y+=1900; return ($y,$mo,$d,$h,$m,$s); } print join ",", datetime=>convert_timezone_datetime(2008,7,3,23,2,3,"America/Denver","America/New_York"); print join ",", registry=>convert_timezone_env_c(2008,7,3,23,2,3,"America/Denver","America/New_York"); print join ",", registry=>convert_timezone_env_c_semaphore(2008,7,3,23,2,3,"America/Denver","America/New_York"); print join ",", "system"=>convert_timezone_system(2008,7,3,23,2,3,"America/Denver","America/New_York"); use Benchmark "timethese"; timethese(-5, { datetime => sub { my ($y,$mo,$d,$h,$m,$s) = convert_timezone_datetime(2008,7,3,23,2,3,"America/Denver","America/New_York"); return }, env_c => sub { my ($y,$mo,$d,$h,$m,$s) = convert_timezone_env_c(2008,7,3,23,2,3,"America/Denver","America/New_York"); return }, env_c_semaphore => sub { my ($y,$mo,$d,$h,$m,$s) = convert_timezone_env_c_semaphore(2008,7,3,23,2,3,"America/Denver","America/New_York"); return }, "system" => sub { my ($y,$mo,$d,$h,$m,$s) = convert_timezone_system(2008,7,3,23,2,3,"America/Denver","America/New_York"); return }, } );