Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Item12202: use strftime to evaluate correct time zone offset (corrected)
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

This version adds 'use POSIX ( strftime );' so that it won't take down
trunk.f.o again :-(

git-svn-id: http://svn.foswiki.org/trunk@15776 0b4bb1d4-4e5a-0410-9cc4-b2b747904278
  • Loading branch information
FlorianSchlichting authored and FlorianSchlichting committed Oct 29, 2012
1 parent d689970 commit 18030f2
Showing 1 changed file with 16 additions and 82 deletions.
98 changes: 16 additions & 82 deletions core/lib/Foswiki/Time.pm
Expand Up @@ -35,6 +35,7 @@ use warnings;

use Assert;
use Foswiki ();
use POSIX qw( strftime );

# Constants
our @ISOMONTH = (
Expand All @@ -61,8 +62,6 @@ our %MON2NUM = (
dec => 11
);

our $TZSTRING; # timezone string for servertime; "Z" or "+01:00" etc.

=begin TML
---++ StaticMethod parseTime( $szDate, $defaultLocal ) -> $iSecs
Expand Down Expand Up @@ -274,13 +273,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 = 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
Expand Down Expand Up @@ -320,90 +332,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
Expand Down

0 comments on commit 18030f2

Please sign in to comment.