When DisplayTimeValues is set to servertime in configure, and then sending an email (e.g. Reset Password), the timestamp in the email header contains 'Local'. This causes problems in email clients with emails being ordered out of chronological sequence.
I have written a fix that replaces 'Local' with the actual offset. The fix handles the correct offset for all time zones, and handles daylight saving. I will do more testing before releasing the fix. All tests so far produce the correct offset.
In Time.pm in the function formatTime is the line:
$tz_str = ( $outputTimeZone eq 'servertime' ) ? 'Local' : 'GMT'
Peter Thoeny tells me that the problem exists in the current code base, and that the above line is a little different in the current code base.
--
TWiki:Main/DonMalcolm
- 09 Dec 2009
Hi
TWiki:Main/DonMalcolm
- welcome to the TWiki as contributor, thx for your discussion about time issue. I am addition your discussion you had with Peter here. We will change the code according to your suggestions soon.
malcdo: Thanks. I found the line: my $tz_str = ( $outputTimeZone eq 'servertime' ) ? 'Local' : 'GMT'; What I want to do is write something like: my $tz_str = ( $outputTimeZone eq 'servertime' ) ? date +%z : 'GMT'; Where date +%z is the Linux date command. [07:09]
peterthoeny: for now as a quick hack you can write: my $tz_str = ( $outputTimeZone eq 'servertime' ) ? '+1100' : 'GMT';
you seem to use an older twiki version, $tz_str looks different now (but has same bug) [07:13]
malcdo: Yes. I am using Ubuntu. Their latest release tends to be a little behind the game.
I suspect, we would always want $tz format to convert to the actual offset and never "Local" when $outputTimeZone is equal to 'servertime'. [07:16]
malcdo: peterthoeny, Thanks very much. By changing 'Local' in Time.pm to '+1100' is exactly the effect I'm after. I will file a bug report. I look forward to a solution that handles day light saving time. [07:34]
peterthoeny: your welcome
--
TWiki:Main/SopanShewale
- 09 Dec 2009
To implement the change for the correct time offset, replace the above mentioned line of code with:
my $tz_str;
if ( $outputTimeZone eq 'servertime' ) {
my( $gsec, $gmin, $ghour, $gday, $gmon, $gyear, $gwday, $tz_day, $tz_hour, $tz_min);
( $gsec, $gmin, $ghour, $gday, $gmon, $gyear, $gwday ) =
gmtime( $epochSeconds );
$tz_day = $wday - $gwday;
$tz_hour = $hour - $ghour;
$tz_min = $min - $gmin;
if ($tz_day > 3) {
$tz_day -= 7;
}
if ($tz_day < -3) {
$tz_day += 7;
}
$tz_hour += (24 * $tz_day);
$tz_min += (60 * $tz_hour);
if ($tz_min < 0) {
$tz_str = '-';
$tz_min *= -1;
} else {
$tz_str = '+';
}
$tz_hour = $tz_min/60;
$tz_min %= 60;
$tz_str .= sprintf('%.2u',$tz_hour);
$tz_str .= sprintf('%.2u',$tz_min);
if (($tz_hour == 0) && ($tz_min == 0)) {
$tz_str = 'GMT';
}
} else {
$tz_str = 'GMT';
}
--
TWiki:Main.DonMalcolm
- 11 Dec 2009
This may not be the most concise solution to this problem. At least it works and is reliable. It does not use any additional modules. It has no system dependencies. It is my original work. It has not been inspired by any other work.
--
TWiki:Main.DonMalcolm
- 15 Dec 2009
Thank you Don! It took some time, but now it is in trunk and 5.0 branch. I made some enhancements to support proper local time diff in ISO date format as well.
Index: Time.pm
===================================================================
--- Time.pm (revision 18879)
+++ Time.pm (working copy)
@@ -195,15 +195,40 @@
$outputTimeZone = 'gmtime';
}
- my( $sec, $min, $hour, $day, $mon, $year, $wday, $tz_str);
- if( $outputTimeZone eq 'servertime' ) {
- ( $sec, $min, $hour, $day, $mon, $year, $wday ) =
- localtime( $epochSeconds );
- $tz_str = 'Local';
+ my( $sec, $min, $hour, $day, $mon, $year, $wday );
+ my $tz_str = 'GMT';
+ if( $outputTimeZone eq 'gmtime' ) {
+ ( $sec, $min, $hour, $day, $mon, $year, $wday ) = gmtime( $epochSeconds );
+
} else {
- ( $sec, $min, $hour, $day, $mon, $year, $wday ) =
- gmtime( $epochSeconds );
- $tz_str = 'GMT';
+ ( $sec, $min, $hour, $day, $mon, $year, $wday ) = localtime( $epochSeconds );
+ if( $formatString =~ /(\$tz|iso)/i ) {
+ # spcial case for local time zone offset calculation
+ my( $tz_day, $tz_hour, $tz_min);
+ my ( $gsec, $gmin, $ghour, $gday, $gmon, $gyear, $gwday ) =
+ gmtime( $epochSeconds );
+ $tz_day = $wday - $gwday;
+ $tz_hour = $hour - $ghour;
+ $tz_min = $min - $gmin;
+ $tz_day -= 7 if ($tz_day > 3);
+ $tz_day += 7 if ($tz_day < -3);
+ $tz_hour += (24 * $tz_day);
+ $tz_min += (60 * $tz_hour);
+ if ($tz_min < 0) {
+ $tz_str = '-';
+ $tz_min *= -1;
+ } else {
+ $tz_str = '+';
+ }
+ $tz_hour = $tz_min/60;
+ $tz_min %= 60;
+ $tz_str .= sprintf('%.2u',$tz_hour);
+ $tz_str .= ':' if( $formatString =~ /iso/i );
+ $tz_str .= sprintf('%.2u',$tz_min);
+ if (($tz_hour == 0) && ($tz_min == 0)) {
+ $tz_str = 'GMT';
+ }
+ }
}
#standard twiki date time formats
@@ -216,14 +241,9 @@
$formatString = '$wday, $day $month $year $hour:$min:$sec $tz';
} elsif ( $formatString =~ /iso/i ) {
# ISO Format, see spec at http://www.w3.org/TR/NOTE-datetime
- # e.g. "2002-12-31T19:30:12Z"
- $formatString = '$year-$mo-$dayT$hour:$min:$sec';
- if( $outputTimeZone eq 'gmtime' ) {
- $formatString = $formatString.'Z';
- } else {
- #TODO: $formatString = $formatString.
- # TZD = time zone designator (Z or +hh:mm or -hh:mm)
- }
+ # "2002-12-31T19:30:12Z" or "2002-12-31T12:30:12-07:00"
+ $formatString = '$year-$mo-$dayT$hour:$min:$sec$tz';
+ $tz_str = 'Z' if( $tz_str eq 'GMT' );
}
$value = $formatString;
@@ -239,9 +259,6 @@
$value =~ s/\$year?/sprintf('%.4u',$year+1900)/gei;
$value =~ s/\$ye/sprintf('%.2u',$year%100)/gei;
$value =~ s/\$epoch/$epochSeconds/gi;
-
- # SMELL: how do we get the different timezone strings (and when
- # we add usertime, then what?)
$value =~ s/\$tz/$tz_str/geoi;
return $value;
--
PeterThoeny - 02 Jun 2010