# HG changeset patch # User Igor Sysoev # Date 1208093592 0 # Node ID 5bb2c374cab2eafcea13a6eff626e6f3ed46b3e0 # Parent 41fd9a2e07553f64add6dc528a91493142d143e5 use more straightforward ngx_gmtime() implementation diff --git a/src/core/ngx_times.c b/src/core/ngx_times.c --- a/src/core/ngx_times.c +++ b/src/core/ngx_times.c @@ -203,14 +203,17 @@ ngx_http_cookie_time(u_char *buf, time_t void ngx_gmtime(time_t t, ngx_tm_t *tp) { - ngx_uint_t n, sec, min, hour, mday, mon, year, wday, yday, days; + ngx_int_t yday; + ngx_uint_t n, sec, min, hour, mday, mon, year, wday, days, leap; /* the calculation is valid for positive time_t only */ + n = (ngx_uint_t) t; days = n / 86400; /* Jaunary 1, 1970 was Thursday */ + wday = (4 + days) % 7; n %= 86400; @@ -219,57 +222,65 @@ ngx_gmtime(time_t t, ngx_tm_t *tp) min = n / 60; sec = n % 60; - /* the algorithm based on Gauss's formula */ + /* + * the algorithm based on Gauss' formula, + * see src/http/ngx_http_parse_time.c + */ + /* days since March 1, 1 BC */ days = days - (31 + 28) + 719527; - year = days * 400 / (365 * 400 + 100 - 4 + 1); + /* + * The "days" should be adjusted to 1 only, however, some March 1st's go + * to previous year, so we adjust them to 2. This causes also shift of the + * last Feburary days to next year, but we catch the case when "yday" + * becomes negative. + */ + + year = (days + 2) * 400 / (365 * 400 + 100 - 4 + 1); + yday = days - (365 * year + year / 4 - year / 100 + year / 400); - mon = (yday + 31) * 12 / 367; - mday = yday - (mon * 367 / 12 - 31); + if (yday < 0) { + leap = (year % 4 == 0) && (year % 100 || (year % 400 == 0)); + yday = 365 + leap + yday; + year--; + } - mon += 2; + /* + * The empirical formula that maps "yday" to month. + * There are at least 10 variants, some of them are: + * mon = (yday + 31) * 15 / 459 + * mon = (yday + 31) * 17 / 520 + * mon = (yday + 31) * 20 / 612 + */ + + mon = (yday + 31) * 10 / 306; + + /* the Gauss' formula that evaluates days before the month */ + + mday = yday - (367 * mon / 12 - 30) + 1; if (yday >= 306) { + year++; + mon -= 10; + /* * there is no "yday" in Win32 SYSTEMTIME * * yday -= 306; */ - year++; - mon -= 12; - - if (mday == 0) { - /* Jaunary 31 */ - mon = 1; - mday = 31; + } else { - } else if (mon == 2) { - - if ((year % 4 == 0) && (year % 100 || (year % 400 == 0))) { - if (mday > 29) { - mon = 3; - mday -= 29; - } + mon += 2; - } else if (mday > 28) { - mon = 3; - mday -= 28; - } - } -/* - * there is no "yday" in Win32 SYSTEMTIME - * - * } else { - * yday += 31 + 28; - * - * if ((year % 4 == 0) && (year % 100 || (year % 400 == 0))) { - * yday++; - * } - */ + /* + * there is no "yday" in Win32 SYSTEMTIME + * + * yday += 31 + 28 + leap; + */ } tp->ngx_tm_sec = (ngx_tm_sec_t) sec;