# Copyright (C) 1995, David Muir Sharnoff # #package Time::Timezone; ## This is release 95.07.10.00 # #=head1 NAME # #Time::Timezone -- miscellaneous timezone manipulations routines # #=head1 SYNOPSIS # # use Time::Timezone; # print tz2zone(); # print tz2zone($ENV{'TZ'}); # print tz2zone($ENV{'TZ'}, time()); # print tz2zone($ENV{'TZ'}, undef, $isdst); # $offset = tz_local_offset(); # $offset = tz_offset($TZ); # #=head1 DESCRIPTION # #This is a collection of miscellaneous timezone manipulation routines. # #C parses the TZ environment variable and returns a timezone #string suitable for inclusion in L-like output. It opionally takes #a timezone string, a time, and a is-dst flag. # #C determins the offset from GMT time in seconds. It #only does the calculation once. # #C determines the offset from GMT in seconds of a specified #timezone. It is supposed to caches results. # #=head1 AUTHOR # #David Muir Sharnoff # #=cut # #require 5.000; # #require Exporter; #@ISA = qw(Exporter); #@EXPORT = qw(tz2zone tz_local_offset tz_offset); #@EXPORT_OK = qw(); # # Parts stolen from code by Paul Foley sub tz2zone { local($TZ, $time, $isdst) = @_; $TZ = defined($ENV{'TZ'}) ? ( $ENV{'TZ'} ? $ENV{'TZ'} : 'GMT' ) : '' unless $TZ; # Hack to deal with 'PST8PDT' format of TZ # Note that this can't deal with all the esoteric forms, but it # does recognize the most common: [:]STDoff[DST[off][,rule]] if (! defined $isdst) { local ($j); $time = time() unless $time; ($j, $j, $j, $j, $j, $j, $j, $j, $isdst) = localtime($time); } # if (defined $tzn{$TZ}->[$isdst]) { # return $tzn{$TZ}->[$isdst]; # } if ($TZ =~ /^([^:\d+\-,]{3,})([+-]?\d{1,2}(:\d{1,2}){0,2})([^\d+\-,]{3,})?/ ){ $TZ = $isdst ? $4 : $1; # $tzn_cache{$TZ} = [ $1, $4 ]; } else { # $tzn_cache{$TZ} = [ $TZ, $TZ ]; } return $TZ; } sub tz_local_offset { local ($time) = @_; $time = time() unless $time; local (@l) = localtime($time); $isdst = @l[8]; if (defined($Timezone'tz_local[$isdst])) { return $Timezone'tz_local[$isdst]; } $Timezone'tz_local[$isdst] = &calc_off($time); return $Timezone'tz_local[$isdst]; } #sub tz_offset #{ # my ($tzn, $time) = @_; # require POSIX; # my $oe = $ENV{'TZ'}; # my $tzo; # $ENV{'TZ'} = $tzn; # &POSIX::tzset(); # # $time = time() unless $time; # my (@l) = localtime($time); # $isdst = @l[8]; # ## caching removed 6/4/95 'cause it doesn't work right. Reason ## unknown. ## if (defined($Timezone::tz_local["$tzn,$isdst"])) { ## return $Timezone::tz_local["$tzn,$isdst"]; ## } ## ## $Timezone::tz_local["$tzn,$isdst"] = # # $tzo = &calc_off($time); # # $ENV{'TZ'} = $oe; # &POSIX::tzset(); # # return $tzo; #} sub calc_off { # can't use my on globs in 5.001 local ($time) = @_; local (@l) = localtime($time); local (@g) = gmtime($time); local ($off); $off = $l[0] - $g[0] + ($l[1] - $g[1]) * 60 + ($l[2] - $g[2]) * 3600; # subscript 7 is yday. if ($l[7] == $g[7]) { # done } elsif ($l[7] == $g[7] + 1) { $off += 86400; } elsif ($l[7] == $g[7] - 1) { $off -= 86400; } elsif ($l[7] < $g[7]) { # crossed over a year boundry! # localtime is beginning of year, gmt is end # therefore local is ahead $off += 86400; } else { $off -= 86400; } return $off; } 1;