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 */
my_difftime(time_t left,time_t right)12 double my_difftime(time_t left, time_t right) {
13 	double diff = (double)left - (double)right;
14 	return diff;
15 }
16 
check_date_max(struct tm * (* date_func)(const time_t *),char * func_name)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 
check_date_min(struct tm * (* date_func)(const time_t *),char * func_name)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 
main(void)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 }
115