Permalink
Browse files

Item12202: use strftime to evaluate correct time zone offset

Needed for correct RSS output:
use strftime to evaluate correct time zone offset changes during start
and end of daylight saving time (note: isotz offset varies depending on
the date in question!)

also revert much of Foswikirev:2393 that has nothing to do with fixing
Item1016; using strftime's %z is much simpler
-

git-svn-id: http://svn.foswiki.org/trunk@15770 0b4bb1d4-4e5a-0410-9cc4-b2b747904278
  • Loading branch information...
FlorianSchlichting FlorianSchlichting
FlorianSchlichting authored and FlorianSchlichting committed Oct 29, 2012
1 parent d60c6dc commit c71f9392badb1df748e4cfd980b5625ac0ed6ee2
Showing with 15 additions and 82 deletions.
  1. +15 −82 core/lib/Foswiki/Time.pm
View
@@ -61,8 +61,6 @@ our %MON2NUM = (
dec => 11
);
our $TZSTRING; # timezone string for servertime; "Z" or "+01:00" etc.
=begin TML
---++ StaticMethod parseTime( $szDate, $defaultLocal ) -> $iSecs
@@ -274,13 +272,26 @@ sub formatTime {
}
my ( $sec, $min, $hour, $day, $mon, $year, $wday, $yday, $isdst );
my ( $tz_str, $isotz_str );
if ( $outputTimeZone eq 'servertime' ) {
( $sec, $min, $hour, $day, $mon, $year, $wday, $yday, $isdst ) =
localtime($epochSeconds);
# SMELL: how do we get the different timezone strings (and when
# we add usertime, then what?)
$tz_str = 'Local';
# isotz_str is date dependant, ie different in summer and winter time
$isotz_str = POSIX::strftime(
'%z', $sec, $min, $hour, $day,
$mon, $year, $wday, $yday, $isdst
);
}
else {
( $sec, $min, $hour, $day, $mon, $year, $wday, $yday ) =
gmtime($epochSeconds);
$tz_str = 'GMT';
$isotz_str = 'Z';
}
#standard Foswiki date time formats
@@ -320,90 +331,12 @@ sub formatTime {
$value =~ s/\$year?/sprintf('%.4u',$year + 1900)/gei;
$value =~ s/\$ye/sprintf('%.2u',$year%100)/gei;
$value =~ s/\$epoch/$epochSeconds/gi;
if ( $value =~ /\$tz/ ) {
my $tz_str;
if ( $outputTimeZone eq 'servertime' ) {
( $sec, $min, $hour, $day, $mon, $year, $wday ) =
localtime($epochSeconds);
# SMELL: how do we get the different timezone strings (and when
# we add usertime, then what?)
$tz_str = 'Local';
}
else {
( $sec, $min, $hour, $day, $mon, $year, $wday ) =
gmtime($epochSeconds);
$tz_str = 'GMT';
}
$value =~ s/\$tz/$tz_str/gei;
}
if ( $value =~ /\$isotz/ ) {
my $tz_str = 'Z';
if ( $outputTimeZone ne 'gmtime' ) {
# servertime
# time zone designator (+hh:mm or -hh:mm)
# cached.
unless ( defined $TZSTRING ) {
my $offset = _tzOffset();
my $sign = ( $offset < 0 ) ? '-' : '+';
$offset = abs($offset);
my $hours = int( $offset / 3600 );
my $mins = int( ( $offset - $hours * 3600 ) / 60 );
if ( $hours || $mins ) {
$TZSTRING = sprintf( "$sign%02d:%02d", $hours, $mins );
}
else {
$TZSTRING = 'Z';
}
}
$tz_str = $TZSTRING;
}
$value =~ s/\$isotz/$tz_str/gei;
}
$value =~ s/\$tz/$tz_str/gi;
$value =~ s/\$isotz/$isotz_str/gi;
return $value;
}
# Get timezone offset from GMT in seconds
# Code taken from CPAN module 'Time' - "David Muir Sharnoff disclaims
# any copyright and puts his contribution to this module in the public
# domain."
# Note that unit tests rely on this function being here.
sub _tzOffset {
my $time = time();
my @l = localtime($time);
my @g = gmtime($time);
my $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 boundary.
# localtime is beginning of year, gmt is end
# therefore local is ahead
$off += 86400;
}
else {
$off -= 86400;
}
return $off;
}
# Returns the ISO8601 week number for a date.
# Year is the real year
# Day of week is 0..6 where 0==Sunday

0 comments on commit c71f939

Please sign in to comment.