New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
timezone and gmt offset as output by POSIX::strftime() are sometimes wrong #6059
Comments
From atatat@atatdot.netwhile perl does reorganize the members of the "struct tm" that gets noting that perl doesn't exactly perform the same way as the correct output (from date): % sh -c 'for t in 1000 900 800 700 600; do \ incorrect output (from perl): % perl -MPOSIX -e 'foreach $t (1000,900,800,700,600) { \ corrected output (from perl): Sat Sep 8 21:46:40 2001 -0400 EDT the patch below makes it work, but you might not like it. :) -------8<-------8<-------8<-------8<-------8<-------8<------- Inline Patch--- ext/POSIX/POSIX.xs.orig Fri Apr 6 00:38:46 2001
+++ ext/POSIX/POSIX.xs Mon Oct 28 12:12:02 2002
@@ -3858,6 +3858,16 @@
mytm.tm_yday = yday;
mytm.tm_isdst = isdst;
mini_mktime(&mytm);
+ /* use libc to normalize the thing -- @@@ */
+ {
+ struct tm mytm2;
+ time_t t;
+ mytm2 = mytm;
+ t = mktime(&mytm2);
+ mytm2 = *localtime(&t);
+ mytm.tm_gmtoff = mytm2.tm_gmtoff;
+ mytm.tm_zone = mytm2.tm_zone;
+ }
len = strftime(tmpbuf, sizeof tmpbuf, fmt, &mytm);
/*
** The following is needed to handle to the situation where
-------8<-------8<-------8<-------8<-------8<-------8<------- Perl Info
|
From @eserte"atatat@atatdot.net (via RT)" <perlbug@perl.org> writes:
Here's (nearly) the same patch which works with bleadperl --- the # #### Patch data follows #### Inline Patch--- ./ext/POSIX/t/posix.t Thu Nov 7 10:37:39 2002
+++ ./ext/POSIX/t/posix.t Fri Nov 8 15:43:04 2002
@@ -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
@@ -182,6 +182,25 @@ try_strftime("Tue Feb 29 00:00:00 2000 0
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 to skip
+
+ 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) {
diff -up 'bleedperl2/util.c' 'bleedperl3/util.c'
Inline Patch--- ./util.c Thu Nov 7 10:43:01 2002
+++ ./util.c Fri Nov 8 15:46:35 2002
@@ -3383,6 +3383,16 @@ Perl_my_strftime(pTHX_ char *fmt, int se
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] */
+#ifdef HAS_MKTIME
+ STMT_START {
+ struct tm mytm2;
+ mytm2 = mytm;
+ mktime(&mytm2);
+ mytm.tm_gmtoff = mytm2.tm_gmtoff;
+ mytm.tm_zone = mytm2.tm_zone;
+ } STMT_END;
+#endif
buflen = 64;
New(0, buf, buflen, char);
len = strftime(buf, buflen, fmt, &mytm);
#### ApplyPatch data follows #### #### End of Patch kit [created: Fri Nov 8 18:30:29 2002] #### Regards, -- tkrevdiff - graphical display of diffs between revisions (RCS or CVS) |
From @doughera88On 8 Nov 2002, Slaven Rezic wrote:
Alas that's not portable. The reason perl doesn't muck with the Fortunately, Configure tests for this. The appropriate %Config variable If you make the util.c code (and the tests!) conditional on those defines, -- |
From @eserteAndy Dougherty <doughera@lafayette.edu> writes:
OK, now with HAS_TM_TM_ZONE and a new HAS_TM_TM_GMTOFF test. But I Regards, # #### Patch data follows #### Inline Patch--- ./config_h.SH Thu Nov 7 10:36:12 2002
+++ ./config_h.SH Fri Nov 8 21:43:50 2002
@@ -2994,10 +2994,15 @@ sed <<!GROK!THIS! >$CONFIG_H -e 's!^#und
* 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 <ustat.h> exists and
diff -up 'bleedperl2/ext/POSIX/t/posix.t' 'bleedperl3/ext/POSIX/t/posix.t'
Inline Patch--- ./ext/POSIX/t/posix.t Thu Nov 7 10:37:39 2002
+++ ./ext/POSIX/t/posix.t Fri Nov 8 21:41:47 2002
@@ -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
@@ -182,6 +182,26 @@ try_strftime("Tue Feb 29 00:00:00 2000 0
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) {
diff -up 'bleedperl2/util.c' 'bleedperl3/util.c'
Inline Patch--- ./util.c Thu Nov 7 10:43:01 2002
+++ ./util.c Fri Nov 8 21:44:10 2002
@@ -3383,6 +3383,20 @@ Perl_my_strftime(pTHX_ char *fmt, int se
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] */
+#ifdef HAS_MKTIME
+ 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);
#### ApplyPatch data follows #### #### End of Patch kit [created: Fri Nov 8 22:12:00 2002] #### -- |
From atatat@atatdot.netthanks for your attention to this. a few comments:
may fail for *anything* older than, say, 1998.
and also on netbsd, which is where i noticed the problem. solaris (2.6, at least) also has %Z, but doesn't have the %z format, also...any chance of this patch (or something like it) being -- |
From goldbb2@earthlink.netSlaven Rezic wrote:
Surely unless at least one of HAS_TM_TM_GMTOFF or HAS_TM_TM_ZONE is #ifdef HAS_MKTIME Into: #if defined(HAS_MKTIME) && ( defined(HAS_TM_TM_GMTOFF) || (HAS_TM_TM_ZONE) ) -- |
From @eserteBenjamin Goldberg <goldbb2@earthlink.net> writes:
OK: # #### Patch data follows #### Inline Patch--- ./config_h.SH Thu Nov 7 10:36:12 2002
+++ ./config_h.SH Fri Nov 8 21:43:50 2002
@@ -2994,10 +2994,15 @@ sed <<!GROK!THIS! >$CONFIG_H -e 's!^#und
* 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 <ustat.h> exists and
diff -up 'bleedperl2/ext/POSIX/t/posix.t' 'bleedperl3/ext/POSIX/t/posix.t'
Inline Patch--- ./ext/POSIX/t/posix.t Thu Nov 7 10:37:39 2002
+++ ./ext/POSIX/t/posix.t Fri Nov 8 21:41:47 2002
@@ -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
@@ -182,6 +182,26 @@ try_strftime("Tue Feb 29 00:00:00 2000 0
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) {
diff -up 'bleedperl2/util.c' 'bleedperl3/util.c'
Inline Patch--- ./util.c Thu Nov 7 10:43:01 2002
+++ ./util.c Sat Nov 9 23:14:07 2002
@@ -3383,6 +3383,20 @@ Perl_my_strftime(pTHX_ char *fmt, int se
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);
#### ApplyPatch data follows #### #### End of Patch kit [created: Sat Nov 9 23:15:52 2002] #### -- Tk-AppMaster: a perl/Tk module launcher designed for handhelds |
From @hvdsSlaven Rezic <slaven.rezic@berlin.de> wrote: Whoops, I dropped this one, sorry. Now applied with thanks as change Hugo |
From @jhiSince the patch was applied, I'm marking the problem ticket as resolved. |
@jhi - Status changed from 'new' to 'resolved' |
Migrated from rt.perl.org#18238 (status was 'resolved')
Searchable as RT18238$
The text was updated successfully, but these errors were encountered: