[xslt] Fixes for EXSLT date
- From: Charles Bozeman <charlie HiWAAY net>
- To: xslt gnome org
- Subject: [xslt] Fixes for EXSLT date
- Date: Sun, 03 Mar 2002 13:04:16 -0600
Hear are some fixes for the date module of libexslt.
ChangeLog:
fixed calculation of day-in-week for negative years
now parses and displays subseconds
fixed bug where 29-Feb was accepted in non-leap years
fixed calculation of time-zone offset when GMT has rolled over to next
day
Also created a test suite for date.
Charlie B.
Index: date.c
===================================================================
RCS file: /cvs/gnome/libxslt/libexslt/date.c,v
retrieving revision 1.8
diff -c -r1.8 date.c
*** date.c 2002/01/17 09:43:35 1.8
--- date.c 2002/03/03 18:37:11
***************
*** 100,116 ****
#define VALID_DAY(day) ((day >= 1) && (day <= 31))
#define VALID_HOUR(hr) ((hr >= 0) && (hr <= 23))
#define VALID_MIN(min) ((min >= 0) && (min <= 59))
! #define VALID_SEC(sec) ((sec >= 0) && (sec <= 59))
#define VALID_TZO(tzo) ((tzo > -1440) && (tzo < 1440))
#define IS_LEAP(y) \
(((y % 4 == 0) && (y % 100 != 0)) || (y % 400 == 0))
static const int daysInMonth[12] =
{ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
#define VALID_MDAY(dt) \
! (((dt->mon == 2) && !IS_LEAP(dt->year) && (dt->day <= 28)) ||\
! (dt->day <= daysInMonth[dt->mon - 1]))
#define VALID_DATE(dt) \
(VALID_YEAR(dt->year) && VALID_MONTH(dt->mon) && VALID_MDAY(dt))
--- 100,119 ----
#define VALID_DAY(day) ((day >= 1) && (day <= 31))
#define VALID_HOUR(hr) ((hr >= 0) && (hr <= 23))
#define VALID_MIN(min) ((min >= 0) && (min <= 59))
! #define VALID_SEC(sec) ((sec >= 0) && (sec < 60))
#define VALID_TZO(tzo) ((tzo > -1440) && (tzo < 1440))
#define IS_LEAP(y) \
(((y % 4 == 0) && (y % 100 != 0)) || (y % 400 == 0))
static const int daysInMonth[12] =
+ { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+ static const int daysInMonthLeap[12] =
{ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
#define VALID_MDAY(dt) \
! (IS_LEAP(dt->year) ? \
! (dt->day <= daysInMonthLeap[dt->mon - 1]) : \
! (dt->day <= daysInMonth[dt->mon - 1]))
#define VALID_DATE(dt) \
(VALID_YEAR(dt->year) && VALID_MONTH(dt->mon) && VALID_MDAY(dt))
***************
*** 133,141 ****
dayInLeapYearByMonth[month - 1] : \
dayInYearByMonth[month - 1]) + day)
- #define DAY_IN_WEEK(yday, yr) \
- (((yr-1)+((yr-1)/4)-((yr-1)/100)+((yr-1)/400)+yday) % 7)
-
/**
* _exsltDateParseGYear:
* @dt: pointer to a date structure
--- 136,141 ----
***************
*** 272,282 ****
#define PARSE_FLOAT(num, cur, invalid) \
PARSE_2_DIGITS(num, cur, invalid); \
if (!invalid && (*cur == '.')) { \
cur++; \
if ((*cur < '0') || (*cur > '9')) \
invalid = 1; \
! while ((*cur < '0') || (*cur > '9')) { \
! static double mult = 1; \
mult /= 10; \
num += (*cur - '0') * mult; \
cur++; \
--- 272,282 ----
#define PARSE_FLOAT(num, cur, invalid) \
PARSE_2_DIGITS(num, cur, invalid); \
if (!invalid && (*cur == '.')) { \
+ double mult = 1; \
cur++; \
if ((*cur < '0') || (*cur > '9')) \
invalid = 1; \
! while ((*cur >= '0') && (*cur <= '9')) { \
mult /= 10; \
num += (*cur - '0') * mult; \
cur++; \
***************
*** 294,301 ****
*/
#define FORMAT_FLOAT(num, cur) \
{ \
! int tmp = (int) num; \
! FORMAT_2_DIGITS(tmp, cur); \
}
/**
--- 294,307 ----
*/
#define FORMAT_FLOAT(num, cur) \
{ \
! xmlChar *sav, *str; \
! if (num < 10.0) \
! *cur++ = '0'; \
! str = xmlXPathCastNumberToString(num); \
! sav = str; \
! while (*str != 0) \
! *cur++ = *str++; \
! xmlFree(sav); \
}
/**
***************
*** 596,602 ****
ret = (exsltDatePtr) xmlMalloc(sizeof(exsltDate));
if (ret == NULL) {
xsltGenericError(xsltGenericErrorContext,
! "exsltDateNewDate: out of memory\n");
return (NULL);
}
memset (ret, 0, sizeof(exsltDate));
--- 602,608 ----
ret = (exsltDatePtr) xmlMalloc(sizeof(exsltDate));
if (ret == NULL) {
xsltGenericError(xsltGenericErrorContext,
! "exsltDateCreateDate: out of memory\n");
return (NULL);
}
memset (ret, 0, sizeof(exsltDate));
***************
*** 654,662 ****
/* determine the time zone offset from local to gm time */
gmTm = gmtime(&secs);
ret->tz_flag = 0;
! ret->tzo = -(((ret->day - gmTm->tm_mday) * 1440) +
! ((ret->hour - gmTm->tm_hour) * 60) +
! (ret->min - gmTm->tm_min));
return ret;
}
--- 660,668 ----
/* determine the time zone offset from local to gm time */
gmTm = gmtime(&secs);
ret->tz_flag = 0;
! ret->tzo = (((ret->day * 1440) + (ret->hour * 60) + ret->min) -
! ((gmTm->tm_mday * 1440) + (gmTm->tm_hour * 60) +
! gmTm->tm_min));
return ret;
}
***************
*** 1229,1234 ****
--- 1235,1268 ----
}
/**
+ * _exsltDayInWeek:
+ * @yday: year day (1-366)
+ * @yr: year
+ *
+ * Determine the day-in-week from @yday and @yr. 0001-01-01 was
+ * a Monday so all other days are calculated from there. Take the
+ * number of years since (or before) add the number of leap years and
+ * the day-in-year and mod by 7. This is a function because negative
+ * years must be handled a little differently and there is no zero year.
+ *
+ * Returns day in week (Sunday = 0)
+ */
+ static int
+ _exsltDateDayInWeek(int yday, long yr)
+ {
+ int ret;
+
+ if (yr < 0) {
+ ret = ((yr + (((yr+1)/4)-((yr+1)/100)+((yr+1)/400)) + yday) % 7);
+ if (ret < 0)
+ ret += 7;
+ } else
+ ret = (((yr-1) + (((yr-1)/4)-((yr-1)/100)+((yr-1)/400)) + yday) % 7);
+
+ return ret;
+ }
+
+ /**
* exsltDateWeekInYear:
* @dateTime: a date/time string
*
***************
*** 1271,1278 ****
}
fdiy = DAY_IN_YEAR(1, 1, dt->year);
! /* 0=Mon, 1=Tue, etc. */
! fdiw = (DAY_IN_WEEK(fdiy, dt->year) + 6) % 7;
ret = DAY_IN_YEAR(dt->day, dt->mon, dt->year) / 7;
--- 1305,1316 ----
}
fdiy = DAY_IN_YEAR(1, 1, dt->year);
!
! /*
! * Determine day-in-week (0=Sun, 1=Mon, etc.) then adjust so Monday
! * is the first day-in-week
! */
! fdiw = (_exsltDateDayInWeek(fdiy, dt->year) + 6) % 7;
ret = DAY_IN_YEAR(dt->day, dt->mon, dt->year) / 7;
***************
*** 1328,1338 ****
}
fdiy = DAY_IN_YEAR(1, dt->mon, dt->year);
! /* 0=Mon, 1=Tue, etc. */
! fdiw = DAY_IN_WEEK(fdiy, dt->year);
!
! /* adjust the fdiw value so that Sunday is last-day-in-week */
! fdiw = (fdiw != 0 ? (fdiw - 1) : 6);
ret = ((dt->day + fdiw) / 7) + 1;
--- 1366,1376 ----
}
fdiy = DAY_IN_YEAR(1, dt->mon, dt->year);
! /*
! * Determine day-in-week (0=Sun, 1=Mon, etc.) then adjust so Monday
! * is the first day-in-week
! */
! fdiw = (_exsltDateDayInWeek(fdiy, dt->year) + 6) % 7;
ret = ((dt->day + fdiw) / 7) + 1;
***************
*** 1526,1532 ****
}
diy = DAY_IN_YEAR(dt->day, dt->mon, dt->year);
! ret = (double) DAY_IN_WEEK(diy, dt->year) + 1;
exsltDateFreeDate(dt);
--- 1564,1571 ----
}
diy = DAY_IN_YEAR(dt->day, dt->mon, dt->year);
!
! ret = (double) _exsltDateDayInWeek(diy, dt->year) + 1;
exsltDateFreeDate(dt);
date.tgz
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]