summaryrefslogtreecommitdiff
path: root/ext/date/lib/tm2unixtime.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/date/lib/tm2unixtime.c')
-rw-r--r--ext/date/lib/tm2unixtime.c77
1 files changed, 51 insertions, 26 deletions
diff --git a/ext/date/lib/tm2unixtime.c b/ext/date/lib/tm2unixtime.c
index e2fa02b69..81befbe10 100644
--- a/ext/date/lib/tm2unixtime.c
+++ b/ext/date/lib/tm2unixtime.c
@@ -16,7 +16,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: tm2unixtime.c 293036 2010-01-03 09:23:27Z sebastian $ */
+/* $Id: tm2unixtime.c 298973 2010-05-04 15:11:41Z derick $ */
#include "timelib.h"
@@ -41,39 +41,64 @@ static int do_range_limit(timelib_sll start, timelib_sll end, timelib_sll adj, t
return 0;
}
-static int do_range_limit_days_relative(timelib_sll *base_y, timelib_sll *base_m, timelib_sll *y, timelib_sll *m, timelib_sll *d)
+static void inc_month(timelib_sll *y, timelib_sll *m)
+{
+ (*m)++;
+ if (*m > 12) {
+ *m -= 12;
+ (*y)++;
+ }
+}
+
+static void dec_month(timelib_sll *y, timelib_sll *m)
+{
+ (*m)--;
+ if (*m < 1) {
+ *m += 12;
+ (*y)--;
+ }
+}
+
+static void do_range_limit_days_relative(timelib_sll *base_y, timelib_sll *base_m, timelib_sll *y, timelib_sll *m, timelib_sll *d, timelib_sll invert)
{
timelib_sll leapyear;
- timelib_sll days_this_month;
- timelib_sll next_month, next_year;
- timelib_sll days_next_month;
+ timelib_sll month, year;
+ timelib_sll days;
do_range_limit(1, 13, 12, base_m, base_y);
- leapyear = timelib_is_leap(*base_y);
- days_this_month = leapyear ? days_in_month_leap[*base_m] : days_in_month[*base_m];
- next_month = (*base_m) + 1;
+ year = *base_y;
+ month = *base_m;
- if (next_month > 12) {
- next_month -= 12;
- next_year = (*base_y) + 1;
+/*
+ printf( "S: Y%d M%d %d %d %d %d\n", year, month, *y, *m, *d, days);
+*/
+ if (!invert) {
+ while (*d < 0) {
+ dec_month(&year, &month);
+ leapyear = timelib_is_leap(year);
+ days = leapyear ? days_in_month_leap[month] : days_in_month[month];
+
+ /* printf( "I Y%d M%d %d %d %d %d\n", year, month, *y, *m, *d, days); */
+
+ *d += days;
+ (*m)--;
+ }
} else {
- next_year = (*base_y);
- }
- leapyear = timelib_is_leap(next_year);
- days_next_month = leapyear ? days_in_month_leap[next_month] : days_in_month[next_month];
+ while (*d < 0) {
+ leapyear = timelib_is_leap(year);
+ days = leapyear ? days_in_month_leap[month] : days_in_month[month];
- if (*d < 0) {
- *d += days_this_month;
- (*m)--;
- return 1;
- }
- if (*d > days_next_month) {
- *d -= days_next_month;
- (*m)++;
- return 1;
+ /* printf( "I Y%d M%d %d %d %d %d\n", year, month, *y, *m, *d, days); */
+
+ *d += days;
+ (*m)--;
+ inc_month(&year, &month);
+ }
}
- return 0;
+ /*
+ printf( "E: Y%d M%d %d %d %d %d\n", year, month, *y, *m, *d, days);
+ */
}
static int do_range_limit_days(timelib_sll *y, timelib_sll *m, timelib_sll *d)
@@ -150,7 +175,7 @@ void timelib_do_rel_normalize(timelib_time *base, timelib_rel_time *rt)
do {} while (do_range_limit(0, 24, 24, &rt->h, &rt->d));
do {} while (do_range_limit(0, 12, 12, &rt->m, &rt->y));
- do {} while (do_range_limit_days_relative(&base->y, &base->m, &rt->y, &rt->m, &rt->d));
+ do_range_limit_days_relative(&base->y, &base->m, &rt->y, &rt->m, &rt->d, rt->invert);
do {} while (do_range_limit(0, 12, 12, &rt->m, &rt->y));
}