From: Slaven Rezic Date: Sat, 9 Nov 2002 23:21:16 +0000 (+0100) Subject: Re: [perl #18238] timezone and gmt offset as output by POSIX::strftime() are sometim... X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=c473feecc28308679db0cf6f8fc1f902de2584d6;p=p5sagit%2Fp5-mst-13.2.git Re: [perl #18238] timezone and gmt offset as output by POSIX::strftime() are sometimes wrong Message-ID: <874raqz8o3.fsf@vran.herceg.de> p4raw-id: //depot/perl@18267 --- diff --git a/config_h.SH b/config_h.SH index 05d8ec2..6bd2039 100644 --- a/config_h.SH +++ b/config_h.SH @@ -2994,10 +2994,15 @@ sed <$CONFIG_H -e 's!^#undef\(.*/\)\*!/\*#define\1 \*!' -e 's!^#un * This symbol, if defined, indicates to the C program that * the struct tm has a tm_zone field. */ +/* HAS_TM_TM_GMTOFF: + * This symbol, if defined, indicates to the C program that + * the struct tm has a tm_gmtoff field. + */ #$i_time I_TIME /**/ #$i_systime I_SYS_TIME /**/ #$i_systimek I_SYS_TIME_KERNEL /**/ #$d_tm_tm_zone HAS_TM_TM_ZONE /**/ +#$d_tm_tm_gmtoff HAS_TM_TM_GMTOFF /**/ /* I_USTAT: * This symbol, if defined, indicates that exists and diff --git a/ext/POSIX/t/posix.t b/ext/POSIX/t/posix.t index 01dba7f..9b0a751 100644 --- a/ext/POSIX/t/posix.t +++ b/ext/POSIX/t/posix.t @@ -11,7 +11,7 @@ BEGIN { } require "./test.pl"; -plan(tests => 61); +plan(tests => 66); use POSIX qw(fcntl_h signal_h limits_h _exit getcwd open read strftime write @@ -183,6 +183,26 @@ try_strftime("Wed Mar 01 00:00:00 2000 061", 0,0,0, 1,2,100); try_strftime("Fri Mar 31 00:00:00 2000 091", 0,0,0, 31,2,100); &POSIX::setlocale(&POSIX::LC_TIME, $lc) if $Config{d_setlocale}; +SKIP: { + # XXX wait for smokers to see which OSs else to skip + skip("No mktime and/or tm_gmtoff", 5) + if !$Config{d_mktime} || !$Config{d_tm_tm_gmtoff} || !$Config{d_tm_tm_zone}; + local $ENV{TZ} = "Europe/Berlin"; + + # May fail for ancient FreeBSD versions. + # %z is not included in POSIX, but valid on Linux and FreeBSD. + foreach $def ([1000,'Sun Sep 9 03:46:40 2001 +0200 CEST'], + [900, 'Thu Jul 9 18:00:00 1998 +0200 CEST'], + [800, 'Tue May 9 08:13:20 1995 +0200 CEST'], + [700, 'Sat Mar 7 21:26:40 1992 +0100 CET'], + [600, 'Thu Jan 5 11:40:00 1989 +0100 CET'], + ) { + my($t, $expected) = @$def; + my @tm = localtime($t*1000000); + is(strftime("%c %z %Z",@tm), $expected, "validating zone setting: $expected"); + } +} + { for my $test (0, 1) { $! = 0; diff --git a/util.c b/util.c index 9a97a6b..b58a1b4 100644 --- a/util.c +++ b/util.c @@ -3388,6 +3388,20 @@ Perl_my_strftime(pTHX_ char *fmt, int sec, int min, int hour, int mday, int mon, mytm.tm_yday = yday; mytm.tm_isdst = isdst; mini_mktime(&mytm); + /* use libc to get the values for tm_gmtoff and tm_zone [perl #18238] */ +#if defined(HAS_MKTIME) && (defined(HAS_TM_TM_GMTOFF) || defined(HAS_TM_TM_ZONE)) + STMT_START { + struct tm mytm2; + mytm2 = mytm; + mktime(&mytm2); +#ifdef HAS_TM_TM_GMTOFF + mytm.tm_gmtoff = mytm2.tm_gmtoff; +#endif +#ifdef HAS_TM_TM_ZONE + mytm.tm_zone = mytm2.tm_zone; +#endif + } STMT_END; +#endif buflen = 64; New(0, buf, buflen, char); len = strftime(buf, buflen, fmt, &mytm);