diff options
author | Igor Sysoev <igor@sysoev.ru> | 2008-04-13 17:33:12 +0400 |
---|---|---|
committer | Igor Sysoev <igor@sysoev.ru> | 2008-04-13 17:33:12 +0400 |
commit | 4611ad3dea1c8c2011c618a67f5f89e2fb077cb4 (patch) | |
tree | db6cf5ef5e69c6a51f70c2b11d619781e6bc1e16 /src/core/ngx_times.c | |
parent | a8372d8a840b093398531a63c94f73055e817c2b (diff) |
use more straightforward ngx_gmtime() implementation
Diffstat (limited to 'src/core/ngx_times.c')
-rw-r--r-- | src/core/ngx_times.c | 85 |
1 files changed, 48 insertions, 37 deletions
diff --git a/src/core/ngx_times.c b/src/core/ngx_times.c index 1ba1210f0..c1798b5bc 100644 --- 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 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--; + } + + /* + * 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; - mon += 2; + /* 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 if (mon == 2) { - - if ((year % 4 == 0) && (year % 100 || (year % 400 == 0))) { - if (mday > 29) { - mon = 3; - mday -= 29; - } - - } 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++; - * } - */ + } else { + + mon += 2; + + /* + * there is no "yday" in Win32 SYSTEMTIME + * + * yday += 31 + 28 + leap; + */ } tp->ngx_tm_sec = (ngx_tm_sec_t) sec; |