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

Test failure on Win32: t/base/date.t test 31 [rt.cpan.org #12068] #8

Open
oalders opened this issue Nov 5, 2019 · 0 comments
Open

Comments

@oalders
Copy link
Member

oalders commented Nov 5, 2019

Migrated from rt.cpan.org#12068 (status was 'open')

Requestors:

From [email protected] on 2005-03-30 10:09:44
:

Relevant output from "perl -Mblib t/base/date.t" is:

'Mar 27 11:02'  =>  1111921320 (1111917720)
not ok 31

This is running bleadperl (@24099) with libwww-perl-5.803 on WinXP.  Built with VC++ 6.0.

Times are different by 3600 seconds.  Is this because I'm in the UK and we've just entered BST?  Note that in the UK DST begins on last Sunday in March, whereas US rule is first Sunday in April.  If I change my clock to Apr 30 then the test succeeds:

'Apr 27 11:06'  =>  1114596360 (1114596360)
ok 31


From [email protected] on 2005-12-06 14:26:17
:

What could LWP do about this? 
Seems like a misconfigured system to me. 

From [email protected] on 2005-12-06 17:58:21
:

[GAAS - Tue Dec  6 09:26:17 2005]:

> What could LWP do about this?
> Seems like a misconfigured system to me.


I don't know what LWP could do about it.  That's why I filed a bug
report rather than send a patch ;-)

The system is not misconfigured any more than any other UK Windows
systems are.  I'm not sure if it is a Windows-specific problem or a
UK-specific problem.

From [email protected] on 2005-12-06 18:18:38
:

Let's see if we can get the following test program to fail: 
 
 use Test::More tests => 2; 
 use Time::Local qw(timelocal); 
 my $t1 = 1111917720; 
 my @t = localtime($t1); 
 my $t2 = timelocal(@t); 
 is($t1, $t2); 
 is(localtime($t1), localtime($t2)); 
 
This should match how HTTP::Date would use timelocal() to convert 
the date string back to a time value.  This succeeds for me.  Can 
you try to run it on your computer? 

From [email protected] on 2005-12-06 18:59:01
:

> Let's see if we can get the following test program to fail: 
>  
>  use Test::More tests => 2; 
>  use Time::Local qw(timelocal); 
>  my $t1 = 1111917720; 
>  my @t = localtime($t1); 
>  my $t2 = timelocal(@t); 
>  is($t1, $t2); 
>  is(localtime($t1), localtime($t2)); 
 
This program fails for me on Windows XP when I change the 
time zone to something called "(GMT) Greenwich middeltid: Dublin, 
Edinburgh, Lisboa, London" and check the box that says something 
like "Adjust time automaticly for summer time" (translated from 
Norwegian).  If I uncheck the summer time adjustment it does not 
fail.  If I select the timezone "(GMT+01:00) Amsterdam, Berline, Bern, 
Oslo,..." it does not fail. 

From [email protected] on 2005-12-07 09:13:12
:

[GAAS - Tue Dec  6 13:59:01 2005]:

> > Let's see if we can get the following test program to fail:
> >
> >  use Test::More tests => 2;
> >  use Time::Local qw(timelocal);
> >  my $t1 = 1111917720;
> >  my @t = localtime($t1);
> >  my $t2 = timelocal(@t);
> >  is($t1, $t2);
> >  is(localtime($t1), localtime($t2));
> 
> This program fails for me on Windows XP when I change the
> time zone to something called "(GMT) Greenwich middeltid: Dublin,
> Edinburgh, Lisboa, London" and check the box that says something
> like "Adjust time automaticly for summer time" (translated from
> Norwegian).  If I uncheck the summer time adjustment it does not
> fail.  If I select the timezone "(GMT+01:00) Amsterdam, Berline, Bern,
> Oslo,..." it does not fail.

Yes, it fails for me too.  My system is in the same time zone that you
used above ("(GMT) Greenwich Mean Time : Dublin, Edinburgh, Libson,
London") and also has "Automatically adjust clock for daylight saving
changes" set.  This is the default configuration in the UK.  As you
found too, switching off that setting or changing to Amsterdam time
makes the test program succeed.

It also fails with $t1 = 1111967999 but succeeds with $t1 = 1111968000.

From [email protected] on 2005-12-07 09:35:02
:

[SHAY - Wed Dec  7 04:13:12 2005]:

> 
> It also fails with $t1 = 1111967999 but succeeds with $t1 =
>    1111968000.


I also meant to say it succeeds with $t1 = 1111885199 but fails with $t1
= 1111885200.

So it fails in the range 1111885200 <= $t1 <= 1111967999.  This is
something like the whole of Sun Mar 27 2005.

I had wondered if this was something to do with the UK summer time rule
being different from the US rule (UK changes on last Sunday in March, US
changes on first Sunday in April), but it that were the problem then I'd
expect the test to fail for the entire week between those two Sundays,
not just on the last Sunday in March.  So now I'm even more confused.

From [email protected] on 2005-12-07 10:15:46
:

[SHAY - Wed Dec  7 04:35:02 2005]:

> 
> So it fails in the range 1111885200 <= $t1 <= 1111967999.  This is
> something like the whole of Sun Mar 27 2005.

Is the following C test program the same thing?

#include <stdio.h>
#include <time.h>
void main(void) {
  time_t t1, t2;
  struct tm *t;
  t1 = 1111917720;
  t = localtime(&t1);
  t2 = mktime(t);
  printf("t1 = %lu, %s", t1, ctime(&t1));
  printf("t2 = %lu, %s", t2, ctime(&t2));
}

If so then it looks more like a Perl / Time::Local problem than a
Windows problem because the above program works fine on the same UK
Windows system (with summer time adjustment set) that the Perl program
fails on.  Output is:

t1 = 1111917720, Sun Mar 27 11:02:00 2005
t2 = 1111917720, Sun Mar 27 11:02:00 2005

Printing out the tm_isdst member of *t shows that it is set to 1.  The
Perl program also has this flag set ($t[8] == 1).

In fact, all nine members of *t are identical to all nine members of @t
in the Perl program, so we have a case of Perl's
Time::Local::timelocal() behaving differently to C's mktime() when both
are given the same input.

[Pause to look at docs...]

Oh, hang on.  timelocal() doesn't actually take nine arguments.  It only
takes the first six, so it doesn't get passed the "isdst" flag.

Simply using POSIX::mktime() instead of Time::Local::timelocal() fixes
the test program.

So it looks like a bug in timelocal(), especially given that its docs
say that it is "always guaranteed to agree with localtime()".

Why doesn't timelocal() take all nine of the arguments that localtime()
returned?  Why isn't it just a wrapper to mktime() anyway?  And the
timelocal() docs don't even mention POSIX::mktime()!

Anyway, can LWP be changed to use POSIX::mktime() instead of
Time::Local::timelocal()?  I could then close this bug and file a new
one under Time::Local instead.

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

No branches or pull requests

1 participant