git-svn: Fix time zone in --localtime
authorWei-Yin Chen (陳威尹) <chen.weiyin@gmail.com>
Mon, 19 Dec 2011 08:11:05 +0000 (16:11 +0800)
committerEric Wong <normalperson@yhbt.net>
Tue, 21 Feb 2012 21:37:31 +0000 (21:37 +0000)
Use numerical form of time zone to replace alphabetic time zone
abbreviation generated by "%Z". "%Z" is not portable and contain
ambiguity for many areas. For example, CST could be "Central
Standard Time" (GMT-0600) and "China Standard Time" (GMT+0800).
Alphabetic time zone abbreviation is meant for human readability,
not for specifying a time zone for machines.

Failed case can be illustrated like this in linux shell:
  > echo $TZ
  Asia/Taipei
  > date +%Z
  CST
  > env TZ=`date +%Z` date
  Mon Dec 19 06:03:04 CST 2011
  > date
  Mon Dec 19 14:03:04 CST 2011

[ew: fixed bad package reference inside Git::SVN::Log]

Signed-off-by: Wei-Yin Chen (陳威尹) <chen.weiyin@gmail.com>
Acked-by: Eric Wong <normalperson@yhbt.net>
git-svn.perl

index bebe38b1ab600be1a0bd4e1b65bb928a68ce7adc..7a92764c657aff80bf03fbc67e021f9892a32b31 100755 (executable)
@@ -2028,6 +2028,7 @@ use Carp qw/croak/;
 use File::Path qw/mkpath/;
 use File::Copy qw/copy/;
 use IPC::Open3;
+use Time::Local;
 use Memoize;  # core since 5.8.0, Jul 2002
 use Memoize::Storable;
 
@@ -3286,6 +3287,14 @@ sub get_untracked {
        \@out;
 }
 
+sub get_tz {
+       # some systmes don't handle or mishandle %z, so be creative.
+       my $t = shift || time;
+       my $gm = timelocal(gmtime($t));
+       my $sign = qw( + + - )[ $t <=> $gm ];
+       return sprintf("%s%02d%02d", $sign, (gmtime(abs($t - $gm)))[2,1]);
+}
+
 # parse_svn_date(DATE)
 # --------------------
 # Given a date (in UTC) from Subversion, return a string in the format
@@ -3318,8 +3327,7 @@ sub parse_svn_date {
                        delete $ENV{TZ};
                }
 
-               my $our_TZ =
-                   POSIX::strftime('%Z', $S, $M, $H, $d, $m - 1, $Y - 1900);
+               my $our_TZ = get_tz();
 
                # This converts $epoch_in_UTC into our local timezone.
                my ($sec, $min, $hour, $mday, $mon, $year,
@@ -5993,7 +6001,6 @@ package Git::SVN::Log;
 use strict;
 use warnings;
 use POSIX qw/strftime/;
-use Time::Local;
 use constant commit_log_separator => ('-' x 72) . "\n";
 use vars qw/$TZ $limit $color $pager $non_recursive $verbose $oneline
             %rusers $show_commit $incremental/;
@@ -6103,11 +6110,8 @@ sub run_pager {
 }
 
 sub format_svn_date {
-       # some systmes don't handle or mishandle %z, so be creative.
        my $t = shift || time;
-       my $gm = timelocal(gmtime($t));
-       my $sign = qw( + + - )[ $t <=> $gm ];
-       my $gmoff = sprintf("%s%02d%02d", $sign, (gmtime(abs($t - $gm)))[2,1]);
+       my $gmoff = Git::SVN::get_tz($t);
        return strftime("%Y-%m-%d %H:%M:%S $gmoff (%a, %d %b %Y)", localtime($t));
 }