diff options
author | Rafael Garcia-Suarez <rgarciasuarez@gmail.com> | 2009-01-03 18:55:29 +0100 |
---|---|---|
committer | Rafael Garcia-Suarez <rgarciasuarez@gmail.com> | 2009-01-03 18:55:29 +0100 |
commit | f433f45e728fb8fd90ae712c4daa4fb4cf2cb6c2 (patch) | |
tree | a495247209955f13920d0cd895025f77c8854f34 /lib/Time | |
parent | 2547c837a73d50421f898a78d070bf820ac97f12 (diff) | |
parent | d4fb0a1f15d1a1c49224933a2cf320efa700d961 (diff) | |
download | perl-f433f45e728fb8fd90ae712c4daa4fb4cf2cb6c2.tar.gz |
Merge branch 'schwern/y2038' into blead
Conflicts:
lib/Time/Local.pm
lib/Time/Local.t
reentr.h
Diffstat (limited to 'lib/Time')
-rw-r--r-- | lib/Time/Local.pm | 44 | ||||
-rwxr-xr-x | lib/Time/Local.t | 75 | ||||
-rw-r--r-- | lib/Time/gmtime.t | 58 | ||||
-rw-r--r-- | lib/Time/localtime.t | 58 |
4 files changed, 69 insertions, 166 deletions
diff --git a/lib/Time/Local.pm b/lib/Time/Local.pm index 1eb0a0240e..fe698d44e7 100644 --- a/lib/Time/Local.pm +++ b/lib/Time/Local.pm @@ -4,7 +4,6 @@ require Exporter; use Carp; use Config; use strict; -use integer; use vars qw( $VERSION @ISA @EXPORT @EXPORT_OK ); $VERSION = '1.1901'; @@ -29,16 +28,8 @@ use constant SECS_PER_MINUTE => 60; use constant SECS_PER_HOUR => 3600; use constant SECS_PER_DAY => 86400; -my $MaxInt; -if ( $^O eq 'MacOS' ) { - # time_t is unsigned... - $MaxInt = ( 1 << ( 8 * $Config{ivsize} ) ) - 1; -} -else { - $MaxInt = ( ( 1 << ( 8 * $Config{ivsize} - 2 ) ) - 1 ) * 2 + 1; -} - -my $MaxDay = int( ( $MaxInt - ( SECS_PER_DAY / 2 ) ) / SECS_PER_DAY ) - 1; +# localtime()'s limit is the year 2**31 +my $MaxDay = 365 * (2**31); # Determine the EPOC day for this machine my $Epoc = 0; @@ -68,13 +59,13 @@ sub _daygm { return $_[3] + ( $Cheat{ pack( 'ss', @_[ 4, 5 ] ) } ||= do { my $month = ( $_[4] + 10 ) % 12; - my $year = ( $_[5] + 1900 ) - ( $month / 10 ); + my $year = $_[5] + 1900 - int($month / 10); ( ( 365 * $year ) - + ( $year / 4 ) - - ( $year / 100 ) - + ( $year / 400 ) - + ( ( ( $month * 306 ) + 5 ) / 10 ) + + int( $year / 4 ) + - int( $year / 100 ) + + int( $year / 400 ) + + int( ( ( $month * 306 ) + 5 ) / 10 ) ) - $Epoc; } @@ -275,16 +266,6 @@ absolute four digit year instead. The scheme above allows interpretation of a wide range of dates, particularly if 4-digit years are used. -=head2 Limits of time_t - -The range of dates that can be actually be handled depends on the size -of C<time_t> (usually a signed integer) on the given -platform. Currently, this is 32 bits for most systems, yielding an -approximate range from Dec 1901 to Jan 2038. - -Both C<timelocal()> and C<timegm()> croak if given dates outside the -supported range. - =head2 Ambiguous Local Times (DST) Because of DST changes, there are many time zones where the same local @@ -307,17 +288,6 @@ for the "Europe/Paris" time zone, the local clock jumped from If the C<timelocal()> function is given a non-existent local time, it will simply return an epoch value for the time one hour later. -=head2 Negative Epoch Values - -Negative epoch (C<time_t>) values are not officially supported by the -POSIX standards, so this module's tests do not test them. On some -systems, they are known not to work. These include MacOS (pre-OSX) and -Win32. - -On systems which do support negative epoch values, this module should -be able to cope with dates before the start of the epoch, down the -minimum value of time_t for the system. - =head1 IMPLEMENTATION These routines are quite efficient and yet are always guaranteed to diff --git a/lib/Time/Local.t b/lib/Time/Local.t index 4f8674fdb9..0f3ccbd1f5 100755 --- a/lib/Time/Local.t +++ b/lib/Time/Local.t @@ -26,10 +26,10 @@ my @time = # leap day [2020, 2, 29, 12, 59, 59], [2030, 7, 4, 17, 07, 06], -# The following test fails on a surprising number of systems -# so it is commented out. The end of the Epoch for a 32-bit signed -# implementation of time_t should be Jan 19, 2038 03:14:07 UTC. -# [2038, 1, 17, 23, 59, 59], # last full day in any tz + [2038, 1, 17, 23, 59, 59], # last full day in any tz + + # more than 2**31 time_t + [2258, 8, 11, 1, 49, 17], ); my @bad_time = @@ -89,42 +89,39 @@ for (@time, @neg_time) { $year -= 1900; $mon--; - SKIP: { - skip '1970 test on VOS fails.', 12 - if $^O eq 'vos' && $year == 70; - skip 'this platform does not support negative epochs.', 12 - if $year < 70 && ! $neg_epoch_ok; - - { - my $year_in = $year < 70 ? $year + 1900 : $year; - my $time = timelocal($sec,$min,$hour,$mday,$mon,$year_in); - - my($s,$m,$h,$D,$M,$Y) = localtime($time); - - is($s, $sec, "timelocal second for @$_"); - is($m, $min, "timelocal minute for @$_"); - is($h, $hour, "timelocal hour for @$_"); - is($D, $mday, "timelocal day for @$_"); - is($M, $mon, "timelocal month for @$_"); - is($Y, $year, "timelocal year for @$_"); - } - - { - my $year_in = $year < 70 ? $year + 1900 : $year; - my $time = timegm($sec,$min,$hour,$mday,$mon,$year_in); - - my($s,$m,$h,$D,$M,$Y) = gmtime($time); - - is($s, $sec, "timegm second for @$_"); - is($m, $min, "timegm minute for @$_"); - is($h, $hour, "timegm hour for @$_"); - is($D, $mday, "timegm day for @$_"); - is($M, $mon, "timegm month for @$_"); - is($Y, $year, "timegm year for @$_"); - } + # Test timelocal() + { + my $year_in = $year < 70 ? $year + 1900 : $year; + my $time = timelocal($sec,$min,$hour,$mday,$mon,$year_in); + + my($s,$m,$h,$D,$M,$Y) = localtime($time); + + is($s, $sec, "timelocal second for @$_"); + is($m, $min, "timelocal minute for @$_"); + is($h, $hour, "timelocal hour for @$_"); + is($D, $mday, "timelocal day for @$_"); + is($M, $mon, "timelocal month for @$_"); + is($Y, $year, "timelocal year for @$_"); + } + + + # Test timegm() + { + my $year_in = $year < 70 ? $year + 1900 : $year; + my $time = timegm($sec,$min,$hour,$mday,$mon,$year_in); + + my($s,$m,$h,$D,$M,$Y) = gmtime($time); + + is($s, $sec, "timegm second for @$_"); + is($m, $min, "timegm minute for @$_"); + is($h, $hour, "timegm hour for @$_"); + is($D, $mday, "timegm day for @$_"); + is($M, $mon, "timegm month for @$_"); + is($Y, $year, "timegm year for @$_"); } } + for (@bad_time) { my($year, $mon, $mday, $hour, $min, $sec) = @$_; $year -= 1900; @@ -167,11 +164,7 @@ for my $p (@years) { "$year $string a leap year" ); } -SKIP: { - skip 'this platform does not support negative epochs.', 6 - unless $neg_epoch_ok; - eval { timegm(0,0,0,29,1,1900) }; like($@, qr/Day '29' out of range 1\.\.28/, 'does not accept leap day in 1900'); diff --git a/lib/Time/gmtime.t b/lib/Time/gmtime.t index 853ec3b6e3..9c77f81570 100644 --- a/lib/Time/gmtime.t +++ b/lib/Time/gmtime.t @@ -3,55 +3,25 @@ BEGIN { chdir 't' if -d 't'; @INC = '../lib'; -} -BEGIN { - our $hasgm; - eval { my $n = gmtime 0 }; - $hasgm = 1 unless $@ && $@ =~ /unimplemented/; - unless ($hasgm) { print "1..0 # Skip: no gmtime\n"; exit 0 } + require "./test.pl"; } +my(@times, @methods); BEGIN { - our @gmtime = gmtime 0; # This is the function gmtime. - unless (@gmtime) { print "1..0 # Skip: gmtime failed\n"; exit 0 } -} - -print "1..10\n"; - -use Time::gmtime; - -print "ok 1\n"; - -my $gmtime = gmtime 0 ; # This is the OO gmtime. - -print "not " unless $gmtime->sec == $gmtime[0]; -print "ok 2\n"; - -print "not " unless $gmtime->min == $gmtime[1]; -print "ok 3\n"; - -print "not " unless $gmtime->hour == $gmtime[2]; -print "ok 4\n"; - -print "not " unless $gmtime->mday == $gmtime[3]; -print "ok 5\n"; - -print "not " unless $gmtime->mon == $gmtime[4]; -print "ok 6\n"; - -print "not " unless $gmtime->year == $gmtime[5]; -print "ok 7\n"; - -print "not " unless $gmtime->wday == $gmtime[6]; -print "ok 8\n"; - -print "not " unless $gmtime->yday == $gmtime[7]; -print "ok 9\n"; - -print "not " unless $gmtime->isdst == $gmtime[8]; -print "ok 10\n"; + @times = (-2**62, -2**50, -2**33, -2**31-1, -1, 0, 1, 2**31-1, 2**33, 2**50, 2**62, time); + @methods = qw(sec min hour mday mon year wday yday isdst); + plan tests => (@times * @methods) + 1; + use_ok Time::gmtime; +} +for my $time (@times) { + my $gmtime = gmtime $time; # This is the OO gmtime. + my @gmtime = CORE::gmtime $time; # This is the gmtime function + for my $method (@methods) { + is $gmtime->$method, shift @gmtime, "gmtime($time)->$method"; + } +} diff --git a/lib/Time/localtime.t b/lib/Time/localtime.t index 357615c780..f300343ff8 100644 --- a/lib/Time/localtime.t +++ b/lib/Time/localtime.t @@ -3,55 +3,25 @@ BEGIN { chdir 't' if -d 't'; @INC = '../lib'; -} -BEGIN { - our $haslocal; - eval { my $n = localtime 0 }; - $haslocal = 1 unless $@ && $@ =~ /unimplemented/; - unless ($haslocal) { print "1..0 # Skip: no localtime\n"; exit 0 } + require "./test.pl"; } +my(@times, @methods); BEGIN { - our @localtime = localtime 0; # This is the function localtime. - unless (@localtime) { print "1..0 # Skip: localtime failed\n"; exit 0 } -} - -print "1..10\n"; - -use Time::localtime; - -print "ok 1\n"; - -my $localtime = localtime 0 ; # This is the OO localtime. - -print "not " unless $localtime->sec == $localtime[0]; -print "ok 2\n"; - -print "not " unless $localtime->min == $localtime[1]; -print "ok 3\n"; - -print "not " unless $localtime->hour == $localtime[2]; -print "ok 4\n"; - -print "not " unless $localtime->mday == $localtime[3]; -print "ok 5\n"; - -print "not " unless $localtime->mon == $localtime[4]; -print "ok 6\n"; - -print "not " unless $localtime->year == $localtime[5]; -print "ok 7\n"; - -print "not " unless $localtime->wday == $localtime[6]; -print "ok 8\n"; - -print "not " unless $localtime->yday == $localtime[7]; -print "ok 9\n"; - -print "not " unless $localtime->isdst == $localtime[8]; -print "ok 10\n"; + @times = (-2**62, -2**50, -2**33, -2**31-1, -1, 0, 1, 2**31-1, 2**33, 2**50, 2**62, time); + @methods = qw(sec min hour mday mon year wday yday isdst); + plan tests => (@times * @methods) + 1; + use_ok Time::localtime; +} +for my $time (@times) { + my $localtime = localtime $time; # This is the OO localtime. + my @localtime = CORE::localtime $time; # This is the localtime function + for my $method (@methods) { + is $localtime->$method, shift @localtime, "localtime($time)->$method"; + } +} |