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 } 115