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