From: Michael G. Schwern Date: Sat, 27 Sep 2008 19:43:22 +0000 (-0400) Subject: Update from y2038 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=750c447b413e71e62138b603e69a4ffe7ba754b2;p=p5sagit%2Fp5-mst-13.2.git Update from y2038 Fix a bug in the code to use the system gmtime, it was using localtime. Define a Year type to avoid mixing years and ints unintentionally. Do some explicit casting to prop up compilers that don't understand X % Y can never be larger than Y. --- diff --git a/localtime64.c b/localtime64.c index ac422e8..72bd68f 100644 --- a/localtime64.c +++ b/localtime64.c @@ -189,16 +189,17 @@ int _check_tm(struct tm *tm) /* The exceptional centuries without leap years cause the cycle to shift by 16 */ -int _cycle_offset(Int64 year) +Year _cycle_offset(Year year) { - const Int64 start_year = 2000; - Int64 year_diff = year - start_year; + const Year start_year = 2000; + Year year_diff = year - start_year; + Year exceptions; if( year > start_year ) year_diff--; - Int64 exceptions = year_diff / 100; - exceptions -= year_diff / 400; + exceptions = year_diff / 100; + exceptions -= year_diff / 400; /* fprintf(stderr, "# year: %lld, exceptions: %lld, year_diff: %lld\n", @@ -225,10 +226,10 @@ int _cycle_offset(Int64 year) It doesn't need the same leap year status since we only care about January 1st. */ -int _safe_year(Int64 year) +int _safe_year(Year year) { int safe_year; - Int64 year_cycle = year + _cycle_offset(year); + Year year_cycle = year + _cycle_offset(year); /* Change non-leap xx00 years to an equivalent */ if( _is_exception_century(year) ) @@ -256,6 +257,7 @@ int _safe_year(Int64 year) return safe_year; } + struct tm *gmtime64_r (const Time64_T *in_time, struct tm *p) { int v_tm_sec, v_tm_min, v_tm_hour, v_tm_mon, v_tm_wday; @@ -263,12 +265,12 @@ struct tm *gmtime64_r (const Time64_T *in_time, struct tm *p) int leap; Int64 m; Time64_T time = *in_time; - Int64 year = 70; + Year year = 70; /* Use the system gmtime() if time_t is small enough */ if( SHOULD_USE_SYSTEM_GMTIME(*in_time) ) { time_t safe_time = *in_time; - localtime_r(&safe_time, p); + gmtime_r(&safe_time, p); assert(_check_tm(p)); return p; } @@ -282,17 +284,20 @@ struct tm *gmtime64_r (const Time64_T *in_time, struct tm *p) p->tm_zone = "UTC"; #endif - v_tm_sec = time % 60; + v_tm_sec = (int)(time % 60); time /= 60; - v_tm_min = time % 60; + v_tm_min = (int)(time % 60); time /= 60; - v_tm_hour = time % 24; + v_tm_hour = (int)(time % 24); time /= 24; v_tm_tday = time; + WRAP (v_tm_sec, v_tm_min, 60); WRAP (v_tm_min, v_tm_hour, 60); WRAP (v_tm_hour, v_tm_tday, 24); - if ((v_tm_wday = (v_tm_tday + 4) % 7) < 0) + + v_tm_wday = (int)((v_tm_tday + 4) % 7); + if (v_tm_wday < 0) v_tm_wday += 7; m = v_tm_tday; @@ -357,7 +362,7 @@ struct tm *gmtime64_r (const Time64_T *in_time, struct tm *p) } p->tm_mday = (int) m + 1; - p->tm_yday = julian_days_by_month[leap][v_tm_mon] + m; + p->tm_yday = (int) julian_days_by_month[leap][v_tm_mon] + m; p->tm_sec = v_tm_sec, p->tm_min = v_tm_min, p->tm_hour = v_tm_hour, p->tm_mon = v_tm_mon, p->tm_wday = v_tm_wday; @@ -371,7 +376,7 @@ struct tm *localtime64_r (const Time64_T *time, struct tm *local_tm) { time_t safe_time; struct tm gm_tm; - Int64 orig_year; + Year orig_year; int month_diff; /* Use the system localtime() if time_t is small enough */ diff --git a/localtime64.h b/localtime64.h index 5bae08a..3771977 100644 --- a/localtime64.h +++ b/localtime64.h @@ -29,7 +29,7 @@ #define SYSTEM_GMTIME_MAX GMTIME_MAX #define SYSTEM_GMTIME_MIN GMTIME_MIN -/* The system localtime will be faster and more correct inside its range */ +/* It'll be faster */ #define USE_SYSTEM_LOCALTIME 1 #define USE_SYSTEM_GMTIME 1 @@ -37,6 +37,7 @@ /* 64 bit types. Set as appropriate for your system. */ typedef Quad_t Time64_T; typedef Quad_t Int64; +typedef Int64 Year; struct tm *gmtime64_r (const Time64_T *, struct tm *); struct tm *localtime64_r (const Time64_T *, struct tm *);