summaryrefslogtreecommitdiff
path: root/lib/Time
diff options
context:
space:
mode:
authorRafael Garcia-Suarez <rgarciasuarez@gmail.com>2009-01-03 18:55:29 +0100
committerRafael Garcia-Suarez <rgarciasuarez@gmail.com>2009-01-03 18:55:29 +0100
commitf433f45e728fb8fd90ae712c4daa4fb4cf2cb6c2 (patch)
treea495247209955f13920d0cd895025f77c8854f34 /lib/Time
parent2547c837a73d50421f898a78d070bf820ac97f12 (diff)
parentd4fb0a1f15d1a1c49224933a2cf320efa700d961 (diff)
downloadperl-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.pm44
-rwxr-xr-xlib/Time/Local.t75
-rw-r--r--lib/Time/gmtime.t58
-rw-r--r--lib/Time/localtime.t58
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";
+ }
+}