Skip to content
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

Bug with Time::Local #2094

Closed
p5pRT opened this issue Jun 15, 2000 · 6 comments
Closed

Bug with Time::Local #2094

p5pRT opened this issue Jun 15, 2000 · 6 comments

Comments

@p5pRT
Copy link

p5pRT commented Jun 15, 2000

Migrated from rt.perl.org#3384 (status was 'resolved')

Searchable as RT3384$

@p5pRT
Copy link
Author

p5pRT commented Jun 15, 2000

From jasonn@noble.vservers.com

Hello. i'm not sure if this is the correct place to report this, if it
is not, please let me know the correct process.

I have discovered a possible bug with the Time​::Local​::timelocal
functionality. I've tested this problem on Linux, BSD and Solaris, they
all seem to have the same problem. I'm running 5.004_04 on BSDI,
5.005_03 on Solaris and 5.6.0 on Red Hat Linux.

The problem seems to only occur using the date 4/2/2000 at 1​:00am and
2​:00am. What I'm doing is using the timelocal function to get a UNIX
date stamp for 4/2/2000 1​:00​:00 and 4/2/2000 1​:59​:59. It correctly
generates this stamp, but when I tell it to do it for 2​:00​:00 and
2​:59​:59, it generates the unix time stamp for 1​:00​:00 and 1​:59​:59
respectively.

I've tried narrowing it down to see what the problem could be, and it
doesn't seem to be a leap year issue (2004 and 1996 work) or a year 2000
issue, as 4/2/1999 works.

Thanks for any light you can shed on the subject.

Jason

--
Jason Noble <jasonn@​noble.vservers.com>
UNIX Administration Developer
HostPro

Reproduction​:
#!/usr/local/bin/perl

use Time​::Local;

$curr_month = 0;
$curr_day = 0;
$curr_year = 0;

  # Don't forget it's 0-11, so 3 is April
  $curr_month = 3;
  $curr_day = 2;
  $curr_year = 100;
  $begin_time = timelocal(0,0,1,$curr_day,$curr_month,$curr_year);

  $end_time = timelocal(59,59,1,$curr_day,$curr_month,$curr_year);

  @​tmp = localtime($begin_time);
  @​tmp2 = localtime($end_time);
  print "Date​: $curr_month $curr_day $curr_year\tBegin​:
$begin_time\t$tmp[2]​:$tmp[1]​:$tmp[0]";
  print "\tEnd​: $end_time\t$tmp2[2]​:$tmp2[1]​:$tmp2[0]\n";
  $begin_time = timelocal(0,0,2,$curr_day,$curr_month,$curr_year);

  $end_time = timelocal(59,59,2,$curr_day,$curr_month,$curr_year);

  @​tmp = localtime($begin_time);
  @​tmp2 = localtime($end_time);
  print "Date​: $curr_month $curr_day $curr_year\tBegin​:
$begin_time\t$tmp[2]​:$tmp[1]​:$tmp[0]";
  print "\tEnd​: $end_time\t$tmp2[2]​:$tmp2[1]​:$tmp2[0]\n";

Output​:
[jasonn@​ratbert perl-5.6.0]$ /tmp/tmp.pl
Date​: 3 2 100 Begin​: 954666000 1​:0​:0 End​: 954669599 1​:59​:59
Date​: 3 2 100 Begin​: 954666000 1​:0​:0 End​: 954669599 1​:59​:59
[jasonn@​ratbert perl-5.6.0]$

@p5pRT
Copy link
Author

p5pRT commented Jun 15, 2000

From @tamias

On Thu, Jun 15, 2000 at 12​:31​:25PM -0700, Jason Noble wrote​:

The problem seems to only occur using the date 4/2/2000 at 1​:00am and
2​:00am. What I'm doing is using the timelocal function to get a UNIX
date stamp for 4/2/2000 1​:00​:00 and 4/2/2000 1​:59​:59. It correctly
generates this stamp, but when I tell it to do it for 2​:00​:00 and
2​:59​:59, it generates the unix time stamp for 1​:00​:00 and 1​:59​:59
respectively.

Daylight Savings Time began at 2am on April 2nd this year.

Ronald

@p5pRT
Copy link
Author

p5pRT commented Jun 15, 2000

From [Unknown Contact. See original ticket]

I'd suspect it has something to do with DST, and the fact that there IS no
04-02-2000-02​:00 in the US. (presuming you're in the US)​:

#!/usr/local/bin/perl
use Time​::Local;
$t = timelocal(0,0,1,2,3,100);
print "$t ", scalar(localtime($t)), "\n";
$t = timelocal(59,59,1,2,3,100);
print "$t ", scalar(localtime($t)), "\n";
$t++;
print "$t ", scalar(localtime($t)), "\n";

$ perl testdst.pl
954666000 Sun Apr 2 01​:00​:00 2000
954669599 Sun Apr 2 01​:59​:59 2000
954669600 Sun Apr 2 03​:00​:00 2000

At 12​:31 PM 6/15/00 -0700, Jason Noble wrote​:

Hello. i'm not sure if this is the correct place to report this, if it
is not, please let me know the correct process.

I have discovered a possible bug with the Time​::Local​::timelocal
functionality. I've tested this problem on Linux, BSD and Solaris, they
all seem to have the same problem. I'm running 5.004_04 on BSDI,
5.005_03 on Solaris and 5.6.0 on Red Hat Linux.

The problem seems to only occur using the date 4/2/2000 at 1​:00am and
2​:00am. What I'm doing is using the timelocal function to get a UNIX
date stamp for 4/2/2000 1​:00​:00 and 4/2/2000 1​:59​:59. It correctly
generates this stamp, but when I tell it to do it for 2​:00​:00 and
2​:59​:59, it generates the unix time stamp for 1​:00​:00 and 1​:59​:59
respectively.

I've tried narrowing it down to see what the problem could be, and it
doesn't seem to be a leap year issue (2004 and 1996 work) or a year 2000
issue, as 4/2/1999 works.

Thanks for any light you can shed on the subject.

Jason

--
Jason Noble <jasonn@​noble.vservers.com>
UNIX Administration Developer
HostPro

Reproduction​:
#!/usr/local/bin/perl

use Time​::Local;

$curr_month = 0;
$curr_day = 0;
$curr_year = 0;

\# Don't forget it's 0\-11\, so 3 is April
$curr\_month = 3;
$curr\_day = 2;
$curr\_year = 100;
    $begin\_time = timelocal\(0\,0\,1\,$curr\_day\,$curr\_month\,$curr\_year\);

    $end\_time = timelocal\(59\,59\,1\,$curr\_day\,$curr\_month\,$curr\_year\);

    @&#8203;tmp = localtime\($begin\_time\);
    @&#8203;tmp2 = localtime\($end\_time\);
    print "Date&#8203;: $curr\_month $curr\_day $curr\_year\\tBegin&#8203;:

$begin_time\t$tmp[2]​:$tmp[1]​:$tmp[0]";
print "\tEnd​: $end_time\t$tmp2[2]​:$tmp2[1]​:$tmp2[0]\n";
$begin_time = timelocal(0,0,2,$curr_day,$curr_month,$curr_year);

    $end\_time = timelocal\(59\,59\,2\,$curr\_day\,$curr\_month\,$curr\_year\);

    @&#8203;tmp = localtime\($begin\_time\);
    @&#8203;tmp2 = localtime\($end\_time\);
    print "Date&#8203;: $curr\_month $curr\_day $curr\_year\\tBegin&#8203;:

$begin_time\t$tmp[2]​:$tmp[1]​:$tmp[0]";
print "\tEnd​: $end_time\t$tmp2[2]​:$tmp2[1]​:$tmp2[0]\n";

Output​:
[jasonn@​ratbert perl-5.6.0]$ /tmp/tmp.pl
Date​: 3 2 100 Begin​: 954666000 1​:0​:0 End​: 954669599 1​:59​:59
Date​: 3 2 100 Begin​: 954666000 1​:0​:0 End​: 954669599 1​:59​:59
[jasonn@​ratbert perl-5.6.0]$

@p5pRT
Copy link
Author

p5pRT commented Jun 15, 2000

From [Unknown Contact. See original ticket]

This brings up something else though... the statement from the documentation​:

"These routines are quite efficient and yet are always
  guaranteed to agree with localtime() and gmtime()."

Is not entirely accurate, because​:

@​foo = (0,0,2,2,3,100);
timelocal(@​foo) != (localtime( timelocal(@​foo) ));

Perhaps instead of "fudging" there, it should determine if it's in the
'skipped hour' and return undef or -1 or something 'special' to indicate
"you've requested a local time which didn't exist".

D

@p5pRT
Copy link
Author

p5pRT commented Jun 15, 2000

From [Unknown Contact. See original ticket]

On Thu, 15 Jun 2000, Derek J. Balling wrote​:

This brings up something else though... the statement from the documentation​:

"These routines are quite efficient and yet are always
guaranteed to agree with localtime() and gmtime()."

Is not entirely accurate, because​:

@​foo = (0,0,2,2,3,100);
timelocal(@​foo) != (localtime( timelocal(@​foo) ));

Perhaps instead of "fudging" there, it should determine if it's in the
'skipped hour' and return undef or -1 or something 'special' to indicate
"you've requested a local time which didn't exist".

Hey, I thought we were DONE with the string decrement thread.

:-)

John.

@p5pRT
Copy link
Author

p5pRT commented Jun 15, 2000

From [Unknown Contact. See original ticket]

That makes total sense now. Sorry I didn't come up with that on my own.

Jason

--
Jason Noble <jasonn@​noble.vservers.com>
UNIX Administration Developer
HostPro

"Derek J. Balling" wrote​:

I'd suspect it has something to do with DST, and the fact that there IS no
04-02-2000-02​:00 in the US. (presuming you're in the US)​:

#!/usr/local/bin/perl
use Time​::Local;
$t = timelocal(0,0,1,2,3,100);
print "$t ", scalar(localtime($t)), "\n";
$t = timelocal(59,59,1,2,3,100);
print "$t ", scalar(localtime($t)), "\n";
$t++;
print "$t ", scalar(localtime($t)), "\n";

$ perl testdst.pl
954666000 Sun Apr 2 01​:00​:00 2000
954669599 Sun Apr 2 01​:59​:59 2000
954669600 Sun Apr 2 03​:00​:00 2000

At 12​:31 PM 6/15/00 -0700, Jason Noble wrote​:

Hello. i'm not sure if this is the correct place to report this, if it
is not, please let me know the correct process.

I have discovered a possible bug with the Time​::Local​::timelocal
functionality. I've tested this problem on Linux, BSD and Solaris, they
all seem to have the same problem. I'm running 5.004_04 on BSDI,
5.005_03 on Solaris and 5.6.0 on Red Hat Linux.

The problem seems to only occur using the date 4/2/2000 at 1​:00am and
2​:00am. What I'm doing is using the timelocal function to get a UNIX
date stamp for 4/2/2000 1​:00​:00 and 4/2/2000 1​:59​:59. It correctly
generates this stamp, but when I tell it to do it for 2​:00​:00 and
2​:59​:59, it generates the unix time stamp for 1​:00​:00 and 1​:59​:59
respectively.

I've tried narrowing it down to see what the problem could be, and it
doesn't seem to be a leap year issue (2004 and 1996 work) or a year 2000
issue, as 4/2/1999 works.

Thanks for any light you can shed on the subject.

Jason

--
Jason Noble <jasonn@​noble.vservers.com>
UNIX Administration Developer
HostPro

Reproduction​:
#!/usr/local/bin/perl

use Time​::Local;

$curr_month = 0;
$curr_day = 0;
$curr_year = 0;

\# Don't forget it's 0\-11\, so 3 is April
$curr\_month = 3;
$curr\_day = 2;
$curr\_year = 100;
    $begin\_time = timelocal\(0\,0\,1\,$curr\_day\,$curr\_month\,$curr\_year\);

    $end\_time = timelocal\(59\,59\,1\,$curr\_day\,$curr\_month\,$curr\_year\);

    @&#8203;tmp = localtime\($begin\_time\);
    @&#8203;tmp2 = localtime\($end\_time\);
    print "Date&#8203;: $curr\_month $curr\_day $curr\_year\\tBegin&#8203;:

$begin_time\t$tmp[2]​:$tmp[1]​:$tmp[0]";
print "\tEnd​: $end_time\t$tmp2[2]​:$tmp2[1]​:$tmp2[0]\n";
$begin_time = timelocal(0,0,2,$curr_day,$curr_month,$curr_year);

    $end\_time = timelocal\(59\,59\,2\,$curr\_day\,$curr\_month\,$curr\_year\);

    @&#8203;tmp = localtime\($begin\_time\);
    @&#8203;tmp2 = localtime\($end\_time\);
    print "Date&#8203;: $curr\_month $curr\_day $curr\_year\\tBegin&#8203;:

$begin_time\t$tmp[2]​:$tmp[1]​:$tmp[0]";
print "\tEnd​: $end_time\t$tmp2[2]​:$tmp2[1]​:$tmp2[0]\n";

Output​:
[jasonn@​ratbert perl-5.6.0]$ /tmp/tmp.pl
Date​: 3 2 100 Begin​: 954666000 1​:0​:0 End​: 954669599 1​:59​:59
Date​: 3 2 100 Begin​: 954666000 1​:0​:0 End​: 954669599 1​:59​:59
[jasonn@​ratbert perl-5.6.0]$

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant