41 #include "qofdate-p.h" 45 AS_STRING_FUNC (QofDateError , ENUM_ERR_LIST)
47 #define match_char(ch1, ch2) if (ch1 != ch2) return NULL 48 # define match_string(cs1, s2) \ 49 (strncasecmp ((cs1), (s2), strlen (cs1)) ? 0 : ((s2) += strlen (cs1), 1)) 52 #define get_number(from, to, n) \ 58 if (*rp < '0' || *rp > '9') \ 60 *error = ERR_OUT_OF_RANGE; \ 61 PERR (" error=%s", QofDateErrorasString (*error)); \ 68 while (--__n > 0 && val * 10 <= to && *rp >= '0' && *rp <= '9'); \ 69 if (val < from || val > to) \ 71 *error = ERR_INVALID_DELIMITER; \ 72 PERR (" error=%s", QofDateErrorasString (*error)); \ 78 # define get_alt_number(from, to, n) \ 79 get_number(from, to, n) 81 #define recursive(new_fmt) \ 82 (*(new_fmt) != '\0' && (rp = strptime_internal (rp, (new_fmt), qd, error)) != NULL) 84 static gchar
const weekday_name[][10] = {
85 "Sunday",
"Monday",
"Tuesday",
"Wednesday",
86 "Thursday",
"Friday",
"Saturday" 88 static gchar
const ab_weekday_name[][4] = {
89 "Sun",
"Mon",
"Tue",
"Wed",
"Thu",
"Fri",
"Sat" 91 static gchar
const month_name[][10] = {
92 "January",
"February",
"March",
"April",
"May",
"June",
93 "July",
"August",
"September",
"October",
"November",
"December" 95 static gchar
const ab_month_name[][4] = {
96 "Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
97 "Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec" 100 # define HERE_D_T_FMT "%a %b %e %H:%M:%S %Y" 101 # define HERE_D_FMT "%m/%d/%y" 102 # define HERE_AM_STR "AM" 103 # define HERE_PM_STR "PM" 104 # define HERE_T_FMT_AMPM "%I:%M:%S %p" 105 # define HERE_T_FMT "%H:%M:%S" 110 static const gushort yeardays[2][13] = {
111 {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365},
112 {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366}
117 set_day_of_the_week (
QofDate * qd)
121 days = days_between (1970, qd->
qd_year);
128 qd->
qd_wday = ((days % 7) + 7) % 7;
132 strptime_internal (
const gchar * rp,
const gchar * fmt,
133 QofDate * qd, QofDateError * error)
135 const gchar * G_GNUC_UNUSED rp_backup;
136 gint64 val, century, want_century;
137 gint want_era, have_wday, want_xday, have_yday;
138 gint have_mon, have_mday, have_uweek, have_wweek;
139 gint week_no, have_I, is_pm, cnt, G_GNUC_UNUSED decided, era_cnt;
140 struct era_entry *era;
150 *error = ERR_NO_ERROR;
152 have_wday = want_xday = have_yday = have_mon = 0;
153 have_mday = have_uweek = have_wweek = 0;
161 while (isspace (*rp))
171 match_char (*fmt++, *rp++);
186 match_char (
'%', *rp++);
191 for (cnt = 0; cnt < 7; ++cnt)
193 if (match_string (weekday_name[cnt], rp)
194 || match_string (ab_weekday_name[cnt], rp))
200 *error = ERR_WEEKDAY_NAME;
201 PERR (
" error=%s", QofDateErrorasString (*error));
211 for (cnt = 0; cnt < 12; ++cnt)
213 if (match_string (month_name[cnt], rp)
214 || match_string (ab_month_name[cnt], rp))
223 *error = ERR_MONTH_NAME;
224 PERR (
" error=%s", QofDateErrorasString (*error));
232 if (!recursive (HERE_D_T_FMT))
234 *error = ERR_LOCALE_DATE_TIME;
235 PERR (
" error=%s", QofDateErrorasString (*error));
242 get_number (0, 99, 2);
249 get_number (1, 31, 2);
255 if (!recursive (
"%Y-%m-%d"))
263 if (!recursive (HERE_D_FMT))
265 *error = ERR_STANDARD_DAY;
266 PERR (
" error=%s", QofDateErrorasString (*error));
274 get_number (0, 23, 2);
282 get_number (1, 12, 2);
288 get_number (1, 366, 3);
294 get_number (1, 12, 2);
301 get_number (0, 59, 2);
309 while (n < 9 && *rp >=
'0' && *rp <=
'9')
311 val = val * 10 + *rp++ -
'0';
320 while (isspace (*rp))
325 if (!match_string (HERE_AM_STR, rp))
327 if (match_string (HERE_PM_STR, rp))
331 *error = ERR_LOCALE_AMPM;
332 PERR (
" error=%s", QofDateErrorasString (*error));
338 if (!recursive (HERE_T_FMT_AMPM))
340 *error = ERR_TIME_AMPM;
341 PERR (
" error=%s", QofDateErrorasString (*error));
346 if (!recursive (
"%H:%M"))
348 *error = ERR_RECURSIVE_R;
349 PERR (
" error=%s", QofDateErrorasString (*error));
360 if (*rp < '0' || *rp >
'9')
363 *error = ERR_SECS_NO_DIGITS;
364 PERR (
" error=%s", QofDateErrorasString (*error));
371 }
while (*rp >=
'0' && *rp <=
'9');
378 get_number (0, 61, 2);
384 if (!recursive (HERE_T_FMT))
386 *error = ERR_RECURSIVE_T;
387 PERR (
" error=%s", QofDateErrorasString (*error));
392 get_number (1, 7, 1);
397 get_number (0, 99, 2);
401 if (*rp < '0' || *rp >
'9')
403 *error = ERR_G_INCOMPLETE;
404 PERR (
" error=%s", QofDateErrorasString (*error));
411 while (*rp >=
'0' && *rp <=
'9');
414 get_number (0, 53, 2);
419 get_number (0, 53, 2);
424 get_number (0, 53, 2);
430 get_number (0, 6, 1);
436 get_number (0, 99, 2);
439 qd->
qd_year = val >= 69 ? val + 2000 : val + 1900;
446 get_number (0, 999999999, 9);
453 PINFO (
" Z format - todo?");
465 if (*rp !=
'+' && *rp !=
'-')
467 *error = ERR_INVALID_Z;
468 PERR (
" error=%s", QofDateErrorasString (*error));
473 while (n < 4 && *rp >=
'0' && *rp <=
'9')
475 val = val * 10 + *rp++ -
'0';
483 *error = ERR_YEAR_DIGITS;
484 PERR (
" error=%s", QofDateErrorasString (*error));
492 *error = ERR_MIN_TO_DECIMAL;
493 PERR (
" error=%s", QofDateErrorasString (*error));
496 val = (val / 100) * 100 + ((val % 100) * 50) / 30;
501 PERR (
" error=%s", QofDateErrorasString (*error));
512 if (*fmt !=
'c' && *fmt !=
'C' && *fmt !=
'y' && *fmt !=
'Y' 513 && *fmt !=
'x' && *fmt !=
'X')
516 *error = ERR_INVALID_FORMAT;
517 PERR (
" error=%s", QofDateErrorasString (*error));
528 get_alt_number (1, 31, 2);
536 get_alt_number (0, 23, 2);
543 get_alt_number (1, 12, 2);
549 get_alt_number (1, 12, 2);
556 get_alt_number (0, 59, 2);
561 get_alt_number (0, 61, 2);
565 get_alt_number (0, 53, 2);
570 get_alt_number (0, 53, 2);
575 get_alt_number (0, 53, 2);
581 get_alt_number (0, 6, 1);
587 get_alt_number (0, 99, 2);
588 qd->
qd_year = val >= 69 ? val : val + 100;
593 *error = ERR_UNKNOWN_ERR;
594 PERR (
" error=%s (first default)",
595 QofDateErrorasString (*error));
602 *error = ERR_UNKNOWN_ERR;
603 PERR (
" error=%s val=%s (second default)",
604 QofDateErrorasString (*error), rp);
620 qd->
qd_year = (century - 19) * 100;
627 *error = ERR_INVALID_ERA;
628 PERR (
" error=%s", QofDateErrorasString (*error));
637 if (want_century && century == -1 && qd->
qd_year < 69)
641 if (want_xday && !have_wday)
643 if (!(have_mon && have_mday) && have_yday)
648 while (yeardays[leap][t_mon] <=
655 yeardays[leap][t_mon - 1] + 1;
657 set_day_of_the_week (qd);
660 if (want_xday && !have_yday)
664 if ((have_uweek || have_wweek) && have_wday)
668 gint save_mon = qd->
qd_mon;
669 gint w_offset = have_uweek ? 0 : 1;
673 set_day_of_the_week (qd);
681 + (week_no - 1) * 7 + save_wday - w_offset);
683 if (!have_mday || !have_mon)
gint64 qd_year
Extended version to cope with full range of dates.
#define PERR(format, args...)
#define PINFO(format, args...)
Full range replacement for struct tm.
glong qd_hour
Signed replacement of struct tm.tm_hour.
glong qd_min
Signed replacement of struct tm.tm_min.
glong qd_mon
Signed replacement of struct tm.tm_mon.
guint16 qof_date_get_yday(gint mday, gint month, gint64 year)
#define qof_date_isleap(year)
glong qd_gmt_off
Calculated value based on struct tm.tm_gmtoff.
gint64 QofTimeSecs
Replacement for time_t.
glong qd_mday
Signed replacement of struct tm.tm_mday.
const gchar * QofLogModule