Skip Menu |

This queue is for tickets about the Date-Calc CPAN distribution.

Report information
The Basics
Id: 57573
Status: rejected
Worked: 15 min
Priority: 0/
Queue: Date-Calc

People
Owner: STBEY [...] cpan.org
Requestors: Andreas.Pfaff [...] meteoswiss.ch
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: (no value)
Fixed in: (no value)



Subject: Bug in System_Clock()
Date: Tue, 18 May 2010 10:45:03 +0200
To: <bug-Date-Calc [...] rt.cpan.org>
From: <Andreas.Pfaff [...] meteoswiss.ch>
Hi, I have discovered a strange behaviour which happens about every 2 weeks and is not reproducable manually. I am using the function System_Clock() in a Perl script running every morning at 2:00 am to get the current date for some calculations and archiving functions. Sometimes this function delivers yesterday as the date and a time (not the current time). The Perl script is called from a batch file on a Windows 2008 server. Fot testing purposes I am printing the date and time from my batch file and the result is correct. When the Perl script is called from that batch file (in the next line) I am printing the date again from within the Perl script and it is printing yesterday: Batch file: date /t 2010-05-18 Perl script: (my $year, my $month, my $day, my $hour, my $min, my $sec, my $doy, my $dow, my $dst) = System_Clock(); print qq($year, $month, $day, $hour, $min, $sec, $doy, $dow, $dst\n); 2010, 5, 17, 15, 18, 40, 137, 1, 0 Even the $dst is wrong as we have DST currently. Am I doing soemthing wrong or is this a bug?? Thanks in advance Andi Pfaff Network Engineer -------------------------------------------------------------- Eidgenössisches Departement des Innern EDI Bundesamt für Meteorologie und Klimatologie MeteoSchweiz Krähbühlstrasse 58 Postfach 514 CH-8044 Zürich, Schweiz Tel. +41 44 256 96 10 Fax +41 44 252 28 43 andreas.pfaff@meteoschweiz.ch www.meteoschweiz.ch MeteoSchweiz, der nationale Wetterdienst, seit Dezember 2004 ISO 9001:2000 zertifiziert
On Tue May 18 04:45:33 2010, Andreas.Pfaff@meteoswiss.ch wrote: Show quoted text
> Hi, > > I have discovered a strange behaviour which happens about every 2 > weeks and is not reproducable manually. I am using the function > System_Clock() in a Perl script running every morning at 2:00 am to > get the current date for some calculations and archiving functions. > Sometimes this function delivers yesterday as the date and a time > (not the current time). The Perl script is called from a batch file > on a Windows 2008 server. > Fot testing purposes I am printing the date and time from my batch > file and the result is correct. When the Perl script is called from > that batch file (in the next line) I am printing the date again > from within the Perl script and it is printing yesterday: > > Batch file: > date /t > 2010-05-18 > > Perl script: > (my $year, my $month, my $day, my $hour, my $min, my $sec, my $doy, my > $dow, my $dst) = System_Clock(); > print qq($year, $month, $day, $hour, $min, $sec, $doy, $dow, $dst\n); > 2010, 5, 17, 15, 18, 40, 137, 1, 0 > > Even the $dst is wrong as we have DST currently. > > Am I doing soemthing wrong or is this a bug?? > > Thanks in advance > Andi Pfaff
Hi Andreas! Since Date::Calc only passes through what it gets from Perl's built-in "localtime()" (in the case when Date::Calc::XS is not installed) or your C runtime library's "localtime()" (in the case of Date::Calc::XS), anything can happen: Date::Calc::PP: sub System_Clock { DATECALC_USAGE('System_Clock([$gmt])') unless ((@_ == 0) or (@_ == 1)); my($year,$month,$day,$hour,$min,$sec,$doy,$dow,$dst,$gmt); if (@_ == 1) { $gmt = shift; } else { $gmt = 0; } if (DateCalc_system_clock(\$year,\$month,\$day, \$hour,\$min,\$sec, \$doy,\$dow,\$dst, $gmt)) { return($year,$month,$day,$hour,$min,$sec,$doy,$dow,$dst); } else { DATECALC_SYSTEM_ERROR('System_Clock'); } } sub DateCalc_system_clock { my($_year,$_month,$_day,$_hour,$_min,$_sec,$_doy,$_dow,$_dst,$gmt) = @_; my($seconds) = time(); if ($seconds >= 0) { $$_dst = 0; if ($gmt) { ($$_sec,$$_min,$$_hour,$$_day,$$_month,$$_year,$$_dow,$$_doy) = gmtime($seconds); } else { ($$_sec,$$_min,$$_hour,$$_day,$$_month,$$_year,$$_dow,$$_doy,$$_dst) = localtime($seconds); } ${$_year} += 1900; ${$_month}++; ${$_dow} = 7 if (${$_dow} == 0); ${$_doy}++; if ($$_dst != 0) { if ($$_dst < 0) { $$_dst = -1; } else { $$_dst = 1; } } return 1; } return 0; } Date::Calc::XS: void DateCalc_System_Clock(...) PPCODE: { Z_int year; Z_int month; Z_int day; Z_int hour; Z_int min; Z_int sec; Z_int doy; Z_int dow; Z_int dst; boolean gmt; if ((items == 0) or (items == 1)) { if (items == 1) gmt = (boolean) SvIV( ST(0) ); else gmt = false; if (DateCalc_system_clock(&year,&month,&day, &hour,&min,&sec, &doy,&dow,&dst, gmt)) { EXTEND(sp,9); PUSHs(sv_2mortal(newSViv((IV)year))); PUSHs(sv_2mortal(newSViv((IV)month))); PUSHs(sv_2mortal(newSViv((IV)day))); PUSHs(sv_2mortal(newSViv((IV)hour))); PUSHs(sv_2mortal(newSViv((IV)min))); PUSHs(sv_2mortal(newSViv((IV)sec))); PUSHs(sv_2mortal(newSViv((IV)doy))); PUSHs(sv_2mortal(newSViv((IV)dow))); PUSHs(sv_2mortal(newSViv((IV)dst))); } else DATECALC_SYSTEM_ERROR; } else croak("Usage: Date::Calc::System_Clock([gmt])"); } boolean DateCalc_system_clock(Z_int *year, Z_int *month, Z_int *day, Z_int *hour, Z_int *min, Z_int *sec, Z_int *doy, Z_int *dow, Z_int *dst, boolean gmt) { time_t seconds; struct tm *date; if (time(&seconds) >= 0) { if (gmt) date = gmtime(&seconds); else date = localtime(&seconds); if (date != NULL) { *year = (*date).tm_year + 1900; *month = (*date).tm_mon + 1; *day = (*date).tm_mday; *hour = (*date).tm_hour; *min = (*date).tm_min; *sec = (*date).tm_sec; *doy = (*date).tm_yday + 1; *dow = (*date).tm_wday; if (*dow == 0) *dow = 7; *dst = (*date).tm_isdst; if (*dst != 0) { if (*dst < 0) *dst = -1; else *dst = 1; } return(true); } } return(false); } Unfortunately there is nothing that I can do about it; except: Have you tried using Date::Calc::XS (just install; it will be used automatically if it is installed) and using Date::Calc::PP, in order to check whether the problem might be related to either the Perl or the XS implementation? Use the following to prevent Date::Calc::XS from being loaded (defaulting to Date::Calc::PP): BEGIN { $Date::Calc::XS_DISABLE = 1; } use Date::Calc qw(:all); You can check the variable $Date::Calc::XS_OK after "use Date::Calc" in order to see which version is actually running. You might also check whether calling "Localtime()" instead of "System_Clock()" makes any difference: #!perl -w use strict; # BEGIN { $Date::Calc::XS_DISABLE = 1; } use Date::Calc qw(:all); print $Date::Calc::XS_OK ? "Date::Calc::XS is running\n" : "Date::Calc::PP is running\n"; (my $year, my $month, my $day, my $hour, my $min, my $sec, my $doy, my $dow, my $dst) = System_Clock(); print qq($year, $month, $day, $hour, $min, $sec, $doy, $dow, $dst\n); ($year,$month,$day, $hour,$min,$sec, $doy,$dow,$dst) = Localtime(); print qq($year, $month, $day, $hour, $min, $sec, $doy, $dow, $dst\n); __END__ This is what I get on my FreeBSD 7.2-STABLE system: $ perl dc.pl Date::Calc::PP is running 2010, 5, 24, 9, 33, 15, 144, 1, 1 2010, 5, 24, 9, 33, 15, 144, 1, 1 $ perl dc.pl Date::Calc::XS is running 2010, 5, 24, 9, 33, 46, 144, 1, 1 2010, 5, 24, 9, 33, 46, 144, 1, 1 And on my Windows XP Media Center Edition SP3: Date::Calc::XS is running 2010, 5, 24, 9, 36, 7, 144, 1, 1 2010, 5, 24, 9, 36, 7, 144, 1, 1 Date::Calc::PP is running 2010, 5, 24, 9, 36, 21, 144, 1, 1 2010, 5, 24, 9, 36, 21, 144, 1, 1 Good luck!
Subject: RE: [rt.cpan.org #57573] Bug in System_Clock()
Date: Wed, 26 May 2010 10:10:54 +0200
To: <bug-Date-Calc [...] rt.cpan.org>
From: <Andreas.Pfaff [...] meteoswiss.ch>
Hi Steffen, in fact even localtime() gave me the wrong date, so it is not Date::Calc which has a bug. Thanks for your help Andi Show quoted text
-----Original Message----- From: Steffen Beyer via RT [mailto:bug-Date-Calc@rt.cpan.org] Sent: Monday, May 24, 2010 9:38 AM To: Pfaff Andreas Subject: [rt.cpan.org #57573] Bug in System_Clock() <URL: https://rt.cpan.org/Ticket/Display.html?id=57573 > On Tue May 18 04:45:33 2010, Andreas.Pfaff@meteoswiss.ch wrote:
> Hi, > > I have discovered a strange behaviour which happens about every 2 > weeks and is not reproducable manually. I am using the function > System_Clock() in a Perl script running every morning at 2:00 am to > get the current date for some calculations and archiving functions. > Sometimes this function delivers yesterday as the date and a time > (not the current time). The Perl script is called from a batch file > on a Windows 2008 server. > Fot testing purposes I am printing the date and time from my batch > file and the result is correct. When the Perl script is called from > that batch file (in the next line) I am printing the date again > from within the Perl script and it is printing yesterday: > > Batch file: > date /t > 2010-05-18 > > Perl script: > (my $year, my $month, my $day, my $hour, my $min, my $sec, my $doy, my > $dow, my $dst) = System_Clock(); > print qq($year, $month, $day, $hour, $min, $sec, $doy, $dow, $dst\n); > 2010, 5, 17, 15, 18, 40, 137, 1, 0 > > Even the $dst is wrong as we have DST currently. > > Am I doing soemthing wrong or is this a bug?? > > Thanks in advance > Andi Pfaff
Hi Andreas! Since Date::Calc only passes through what it gets from Perl's built-in "localtime()" (in the case when Date::Calc::XS is not installed) or your C runtime library's "localtime()" (in the case of Date::Calc::XS), anything can happen: Date::Calc::PP: sub System_Clock { DATECALC_USAGE('System_Clock([$gmt])') unless ((@_ == 0) or (@_ == 1)); my($year,$month,$day,$hour,$min,$sec,$doy,$dow,$dst,$gmt); if (@_ == 1) { $gmt = shift; } else { $gmt = 0; } if (DateCalc_system_clock(\$year,\$month,\$day, \$hour,\$min,\$sec, \$doy,\$dow,\$dst, $gmt)) { return($year,$month,$day,$hour,$min,$sec,$doy,$dow,$dst); } else { DATECALC_SYSTEM_ERROR('System_Clock'); } } sub DateCalc_system_clock { my($_year,$_month,$_day,$_hour,$_min,$_sec,$_doy,$_dow,$_dst,$gmt) = @_; my($seconds) = time(); if ($seconds >= 0) { $$_dst = 0; if ($gmt) { ($$_sec,$$_min,$$_hour,$$_day,$$_month,$$_year,$$_dow,$$_doy) = gmtime($seconds); } else { ($$_sec,$$_min,$$_hour,$$_day,$$_month,$$_year,$$_dow,$$_doy,$$_dst) = localtime($seconds); } ${$_year} += 1900; ${$_month}++; ${$_dow} = 7 if (${$_dow} == 0); ${$_doy}++; if ($$_dst != 0) { if ($$_dst < 0) { $$_dst = -1; } else { $$_dst = 1; } } return 1; } return 0; } Date::Calc::XS: void DateCalc_System_Clock(...) PPCODE: { Z_int year; Z_int month; Z_int day; Z_int hour; Z_int min; Z_int sec; Z_int doy; Z_int dow; Z_int dst; boolean gmt; if ((items == 0) or (items == 1)) { if (items == 1) gmt = (boolean) SvIV( ST(0) ); else gmt = false; if (DateCalc_system_clock(&year,&month,&day, &hour,&min,&sec, &doy,&dow,&dst, gmt)) { EXTEND(sp,9); PUSHs(sv_2mortal(newSViv((IV)year))); PUSHs(sv_2mortal(newSViv((IV)month))); PUSHs(sv_2mortal(newSViv((IV)day))); PUSHs(sv_2mortal(newSViv((IV)hour))); PUSHs(sv_2mortal(newSViv((IV)min))); PUSHs(sv_2mortal(newSViv((IV)sec))); PUSHs(sv_2mortal(newSViv((IV)doy))); PUSHs(sv_2mortal(newSViv((IV)dow))); PUSHs(sv_2mortal(newSViv((IV)dst))); } else DATECALC_SYSTEM_ERROR; } else croak("Usage: Date::Calc::System_Clock([gmt])"); } boolean DateCalc_system_clock(Z_int *year, Z_int *month, Z_int *day, Z_int *hour, Z_int *min, Z_int *sec, Z_int *doy, Z_int *dow, Z_int *dst, boolean gmt) { time_t seconds; struct tm *date; if (time(&seconds) >= 0) { if (gmt) date = gmtime(&seconds); else date = localtime(&seconds); if (date != NULL) { *year = (*date).tm_year + 1900; *month = (*date).tm_mon + 1; *day = (*date).tm_mday; *hour = (*date).tm_hour; *min = (*date).tm_min; *sec = (*date).tm_sec; *doy = (*date).tm_yday + 1; *dow = (*date).tm_wday; if (*dow == 0) *dow = 7; *dst = (*date).tm_isdst; if (*dst != 0) { if (*dst < 0) *dst = -1; else *dst = 1; } return(true); } } return(false); } Unfortunately there is nothing that I can do about it; except: Have you tried using Date::Calc::XS (just install; it will be used automatically if it is installed) and using Date::Calc::PP, in order to check whether the problem might be related to either the Perl or the XS implementation? Use the following to prevent Date::Calc::XS from being loaded (defaulting to Date::Calc::PP): BEGIN { $Date::Calc::XS_DISABLE = 1; } use Date::Calc qw(:all); You can check the variable $Date::Calc::XS_OK after "use Date::Calc" in order to see which version is actually running. You might also check whether calling "Localtime()" instead of "System_Clock()" makes any difference: #!perl -w use strict; # BEGIN { $Date::Calc::XS_DISABLE = 1; } use Date::Calc qw(:all); print $Date::Calc::XS_OK ? "Date::Calc::XS is running\n" : "Date::Calc::PP is running\n"; (my $year, my $month, my $day, my $hour, my $min, my $sec, my $doy, my $dow, my $dst) = System_Clock(); print qq($year, $month, $day, $hour, $min, $sec, $doy, $dow, $dst\n); ($year,$month,$day, $hour,$min,$sec, $doy,$dow,$dst) = Localtime(); print qq($year, $month, $day, $hour, $min, $sec, $doy, $dow, $dst\n); __END__ This is what I get on my FreeBSD 7.2-STABLE system: $ perl dc.pl Date::Calc::PP is running 2010, 5, 24, 9, 33, 15, 144, 1, 1 2010, 5, 24, 9, 33, 15, 144, 1, 1 $ perl dc.pl Date::Calc::XS is running 2010, 5, 24, 9, 33, 46, 144, 1, 1 2010, 5, 24, 9, 33, 46, 144, 1, 1 And on my Windows XP Media Center Edition SP3: Date::Calc::XS is running 2010, 5, 24, 9, 36, 7, 144, 1, 1 2010, 5, 24, 9, 36, 7, 144, 1, 1 Date::Calc::PP is running 2010, 5, 24, 9, 36, 21, 144, 1, 1 2010, 5, 24, 9, 36, 21, 144, 1, 1 Good luck!
On Wed May 26 04:11:10 2010, Andreas.Pfaff@meteoswiss.ch wrote: Show quoted text
> Hi Steffen, > in fact even localtime() gave me the wrong date, so it is not Date::Calc > which has a bug. > Thanks for your help > Andi
You're welcome of course! I therefore close (reject) this bug report.