Commit | Line | Data |
---|---|---|
1b289682 MB |
1 | The y2038 implementation for perl |
2 | =========================================================================== | |
3 | This is an implementation of POSIX time.h which solves the year 2038 bug on | |
4 | systems where time_t is only 32 bits. It is implemented in bog-standard | |
5d0d7ae4 | 5 | ANSI C. The latest version can be found at https://github.com/evalEmpire/y2038 |
1b289682 MB |
6 | |
7 | It makes use of the system's native 32 bit functions to perform time zone | |
8 | and daylight savings time calculations and thus does *not* need to ship its | |
9 | own time zone table. | |
10 | ||
11 | time64.h currently implements three public functions, localtime64_r(), | |
12 | gmtime64_r() and timegm64(). They are implementations of localtime_r(), | |
13 | gmtime_r() and timegm64(). | |
14 | ||
15 | To install, simply copy time64.c and time64.h into your project and make | |
16 | use of the functions. | |
17 | ||
18 | To test, run "make test". You must have Perl, prove (which comes with a | |
19 | recent version of the Test::Harness Perl module) and bzdiff installed to | |
20 | run the full test suite. It will do a number of unit tests, plus test | |
21 | against a large table of known good values in different time zones. | |
22 | ||
23 | Limitations, Issues, etc... | |
24 | --------------------------- | |
25 | localtime64_r() gets its time zone and daylight savings time information by | |
47e01c32 | 26 | mapping the future year back to a similar one between 2010 and 2037, safe |
1b289682 MB |
27 | for localtime_r(). The calculations are accurate according to current time |
28 | zone and daylight savings information, but may become inaccurate if a | |
29 | change is made that takes place after 2010. | |
30 | ||
31 | Future versions will probe for a 64 bit safe system localtime_r() and | |
32 | gmtime_r() and use that. | |
33 | ||
34 | The maximum date is still limited by your tm struct. Most 32 bit systems | |
35 | use a signed integer tm_year which means the practical upper limit is the | |
36 | year 2147483647 which is somewhere around 2**54. You can use a 64 bit | |
37 | clean tm struct by setting USE_TM64 in time64.h | |
38 | ||
39 | Portability | |
40 | ----------- | |
41 | I would like to add some configuration detection stuff in the future, but | |
42 | for now all I can do is document the assumptions... | |
43 | ||
44 | This code assumes that long longs are 64 bit integers which is technically | |
45 | in violation of the C standard. This can be changed in time64.h by | |
46 | changing the Time64_T and Int64 typedefs. | |
47 | ||
48 | There are a number of configuration options in time64.h. | |
49 | ||
50 | Configure variables | |
51 | ------------------- | |
52 | Configure probes for the maximum and minimum values that gmtime () and | |
53 | localtime () accept on the local system. Configure however is only used on | |
54 | unix-like systems. For windows and VMS these values are hard-coded. You can | |
55 | use timecheck.c in the Porting directory to check those values yourself, | |
56 | using the same technique that is used in Configure based on bit-shifting: | |
57 | ||
90c09c68 | 58 | $ cd Porting |
1b289682 MB |
59 | $ cc -O -o timecheck timecheck.c |
60 | $ ./timecheck | |
61 | ====================== | |
62 | Sizeof time_t = 8 | |
63 | gmtime () boundaries: | |
64 | 8: 0x00f0c2ab7c54a97f: 2147485547-12-31 23:59:59 | |
65 | 8: -0x0000000e79747c00: 0-01-01 00:00:00 | |
66 | localtime () boundaries: | |
67 | 8: 0x00f0c2ab7c549b6f: 2147485547-12-31 23:59:59 | |
68 | 8: -0x0000000e79748094: 0-01-01 00:00:00 | |
69 | Configure variables: | |
70 | sGMTIME_max='67768036191676799' | |
71 | sGMTIME_min='-62167219200' | |
72 | sLOCALTIME_max='67768036191673199' | |
73 | sLOCALTIME_min='-62167220372' | |
74 | ||
75 | In the rare case that your system uses a double for time_t, you can use the | |
76 | alternate approach to test for these values: | |
77 | ||
78 | $ cd perl/Porting | |
79 | $ cc -O -o timecheck2{,.c} | |
80 | $ ./timecheck2 | |
81 | gmtime max 67768036191676800 | |
82 | localtime max 67768036191673200 | |
83 | gmtime min -67768040609740800 | |
84 | localtime min -67768040609741968 |