Commit | Line | Data |
---|---|---|
233e9d1c JV |
1 | /* A little program to test the limits of your system's time functions |
2 | * See Porting/README.y2038 for details | |
3 | */ | |
1b289682 MB |
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 | } |