This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Create inversion list for Assigned code points
[perl5.git] / Porting / timecheck2.c
1 /* A little program to test the limits of your system's time functions
2  * See Porting/README.y2038 for details
3  */
4
5 #include <time.h>
6 #include <stdio.h>
7 #include <math.h>
8
9 time_t Time_Zero = 0;
10
11 /* Visual C++ 2008's difftime() can't do negative times */
12 double my_difftime(time_t left, time_t right) {
13         double diff = (double)left - (double)right;
14         return diff;
15 }
16
17 void check_date_max( struct tm * (*date_func)(const time_t *), char *func_name ) {
18     struct tm *date;
19     time_t time = 0;
20     time_t last_time = 0;
21     time_t time_change;
22     int i;
23
24     for (i = 0; i <= 63; i++) {
25         date = (*date_func)(&time);
26
27         /* date_func() broke or tm_year overflowed */
28         if(date == NULL || date->tm_year < 69)
29           break;
30
31         last_time = time;
32         time += time + 1;
33
34         /* time_t overflowed */
35         if( time < last_time )
36             break;
37     }
38
39     /* Binary search for the exact failure point */
40     time = last_time;
41     time_change = last_time / 2;
42
43     do {
44         time += time_change;
45
46         date = (*date_func)(&time);
47
48         /* date_func() broke or tm_year overflowed or time_t overflowed */
49         if(date == NULL || date->tm_year < 69 || time < last_time) {
50             time = last_time;
51             time_change = time_change / 2;
52         }
53         else {
54             last_time = time;
55         }
56     } while(time_change > 0);
57
58     printf("%20s max %.0f\n", func_name, my_difftime(last_time, Time_Zero));
59 }
60
61
62 void check_date_min( struct tm * (*date_func)(const time_t *), char *func_name ) {
63     struct tm *date;
64     time_t time = -1;
65     time_t last_time = 0;
66     time_t time_change;
67     int i;
68
69     for (i = 1; i <= 63; i++) {
70         date = (*date_func)(&time);
71
72         /* date_func() broke or tm_year underflowed */
73         if(date == NULL || date->tm_year > 70)
74             break;
75
76         last_time = time;
77         time += time;
78
79         /* time_t underflowed */
80         if( time > last_time )
81             break;
82     }
83
84     /* Binary search for the exact failure point */
85     time = last_time;
86     time_change = last_time / 2;
87
88     do {
89         time += time_change;
90
91         date = (*date_func)(&time);
92
93         /* gmtime() broke or tm_year overflowed or time_t overflowed */
94         if(date == NULL || date->tm_year > 70 || time > last_time) {
95             time = last_time;
96             time_change = time_change / 2;
97         }
98         else {
99             last_time = time;
100         }
101     } while(time_change < 0);
102
103     printf("%20s min %.0f\n", func_name, my_difftime(last_time, Time_Zero));
104 }
105
106
107 int main(void) {
108     check_date_max(gmtime, "gmtime");
109     check_date_max(localtime, "localtime");
110     check_date_min(gmtime, "gmtime");
111     check_date_min(localtime, "localtime");
112
113     return 0;
114 }