use more straightforward ngx_gmtime() implementation
diff --git a/src/core/ngx_times.c b/src/core/ngx_times.c
index 1ba1210..c1798b5 100644
--- a/src/core/ngx_times.c
+++ b/src/core/ngx_times.c
@@ -203,14 +203,17 @@
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 @@
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;
+ } else {
- if (mday == 0) {
- /* Jaunary 31 */
- mon = 1;
- mday = 31;
+ mon += 2;
- } 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++;
- * }
- */
+ /*
+ * there is no "yday" in Win32 SYSTEMTIME
+ *
+ * yday += 31 + 28 + leap;
+ */
}
tp->ngx_tm_sec = (ngx_tm_sec_t) sec;