mirror of
https://github.com/Perl/perl5.git
synced 2026-01-26 16:39:36 +00:00
85 lines
3.5 KiB
Plaintext
85 lines
3.5 KiB
Plaintext
The y2038 implementation for perl
|
|
===========================================================================
|
|
This is an implementation of POSIX time.h which solves the year 2038 bug on
|
|
systems where time_t is only 32 bits. It is implemented in bog-standard
|
|
ANSI C. The latest version can be found at https://github.com/evalEmpire/y2038
|
|
|
|
It makes use of the system's native 32 bit functions to perform time zone
|
|
and daylight savings time calculations and thus does *not* need to ship its
|
|
own time zone table.
|
|
|
|
time64.h currently implements three public functions, localtime64_r(),
|
|
gmtime64_r() and timegm64(). They are implementations of localtime_r(),
|
|
gmtime_r() and timegm64().
|
|
|
|
To install, simply copy time64.c and time64.h into your project and make
|
|
use of the functions.
|
|
|
|
To test, run "make test". You must have Perl, prove (which comes with a
|
|
recent version of the Test::Harness Perl module) and bzdiff installed to
|
|
run the full test suite. It will do a number of unit tests, plus test
|
|
against a large table of known good values in different time zones.
|
|
|
|
Limitations, Issues, etc...
|
|
---------------------------
|
|
localtime64_r() gets its time zone and daylight savings time information by
|
|
mapping the future year back to a similar one between 2010 and 2037, safe
|
|
for localtime_r(). The calculations are accurate according to current time
|
|
zone and daylight savings information, but may become inaccurate if a
|
|
change is made that takes place after 2010.
|
|
|
|
Future versions will probe for a 64 bit safe system localtime_r() and
|
|
gmtime_r() and use that.
|
|
|
|
The maximum date is still limited by your tm struct. Most 32 bit systems
|
|
use a signed integer tm_year which means the practical upper limit is the
|
|
year 2147483647 which is somewhere around 2**54. You can use a 64 bit
|
|
clean tm struct by setting USE_TM64 in time64.h
|
|
|
|
Portability
|
|
-----------
|
|
I would like to add some configuration detection stuff in the future, but
|
|
for now all I can do is document the assumptions...
|
|
|
|
This code assumes that long longs are 64 bit integers which is technically
|
|
in violation of the C standard. This can be changed in time64.h by
|
|
changing the Time64_T and Int64 typedefs.
|
|
|
|
There are a number of configuration options in time64.h.
|
|
|
|
Configure variables
|
|
-------------------
|
|
Configure probes for the maximum and minimum values that gmtime () and
|
|
localtime () accept on the local system. Configure however is only used on
|
|
unix-like systems. For windows and VMS these values are hard-coded. You can
|
|
use timecheck.c in the Porting directory to check those values yourself,
|
|
using the same technique that is used in Configure based on bit-shifting:
|
|
|
|
$ cd Porting
|
|
$ cc -O -o timecheck timecheck.c
|
|
$ ./timecheck
|
|
======================
|
|
Sizeof time_t = 8
|
|
gmtime () boundaries:
|
|
8: 0x00f0c2ab7c54a97f: 2147485547-12-31 23:59:59
|
|
8: -0x0000000e79747c00: 0-01-01 00:00:00
|
|
localtime () boundaries:
|
|
8: 0x00f0c2ab7c549b6f: 2147485547-12-31 23:59:59
|
|
8: -0x0000000e79748094: 0-01-01 00:00:00
|
|
Configure variables:
|
|
sGMTIME_max='67768036191676799'
|
|
sGMTIME_min='-62167219200'
|
|
sLOCALTIME_max='67768036191673199'
|
|
sLOCALTIME_min='-62167220372'
|
|
|
|
In the rare case that your system uses a double for time_t, you can use the
|
|
alternate approach to test for these values:
|
|
|
|
$ cd perl/Porting
|
|
$ cc -O -o timecheck2{,.c}
|
|
$ ./timecheck2
|
|
gmtime max 67768036191676800
|
|
localtime max 67768036191673200
|
|
gmtime min -67768040609740800
|
|
localtime min -67768040609741968
|