X-Git-Url: https://diplodocus.org/git/nmh/blobdiff_plain/68bb948f6c1484de72e07f315b9dd1694037acfd..ca3143890523c6d3092f0e7c3f9aceffa698dbd9:/sbr/datetime.c?ds=sidebyside diff --git a/sbr/datetime.c b/sbr/datetime.c index 34287b23..48f02d45 100644 --- a/sbr/datetime.c +++ b/sbr/datetime.c @@ -1,5 +1,4 @@ -/* - * datetime.c -- functions for manipulating RFC 5545 date-time values +/* datetime.c -- functions for manipulating RFC 5545 date-time values * * This code is Copyright (c) 2014, by the authors of nmh. * See the COPYRIGHT file in the root directory of the nmh @@ -62,7 +61,10 @@ parse_datetime (const char *datetime, const char *zone, int dst, struct tws *tws) { char utc_indicator; int form_1 = 0; - int items_matched = + int items_matched; + + memset(tws, 0, sizeof *tws); + items_matched = sscanf (datetime, "%4d%2d%2dT%2d%2d%2d%c", &tws->tw_year, &tws->tw_mon, &tws->tw_mday, &tws->tw_hour, &tws->tw_min, &tws->tw_sec, @@ -72,7 +74,7 @@ parse_datetime (const char *datetime, const char *zone, int dst, if (items_matched == 7) { /* The 'Z' must be capital according to RFC 5545 Sec. 3.3.5. */ if (utc_indicator != 'Z') { - advise (NULL, "%s has invalid timezone indicator of 0x%x", + inform("%s has invalid timezone indicator of 0x%x", datetime, utc_indicator); return NOTOK; } @@ -80,12 +82,16 @@ parse_datetime (const char *datetime, const char *zone, int dst, form_1 = 1; } - if (items_matched >= 6) { + /* items_matched of 3 is for, e.g., 20151230. Assume that means + the entire day. The time fields of the tws struct were + initialized to 0 by the memset() above. */ + if (items_matched >= 6 || items_matched == 3) { int offset = atoi (zone ? zone : "0"); /* struct tws defines tw_mon over [0, 11]. */ --tws->tw_mon; + /* Fill out rest of tws, i.e., its tw_wday and tw_flags. */ set_dotw (tws); /* set_dotw() sets TW_SIMP. Replace that with TW_SEXP so that dasctime() outputs the dotw before the date instead of after. */ @@ -136,9 +142,9 @@ parse_datetime (const char *datetime, const char *zone, int dst, } return OK; - } else { - return NOTOK; } + + return NOTOK; } tzdesc_t @@ -170,7 +176,7 @@ load_timezones (const contentline *clines) { params->start_dt = tws.tw_clock; } } else { - advise (NULL, "failed to parse start time %s for %s", + inform("failed to parse start time %s for %s", params->dtstart, in_standard ? "standard" : "daylight"); return NULL; @@ -210,7 +216,7 @@ load_timezones (const contentline *clines) { ! strcasecmp ("VTIMEZONE", node->value)) { in_vtimezone = 1; - timezone = mh_xcalloc (1, sizeof (struct tzdesc)); + NEW0(timezone); if (timezones) { tzdesc_t t; @@ -262,7 +268,8 @@ rrule_clock (const char *rrule, const char *starttime, const char *zone, unsigned int year) { time_t clock = 0; - if (nmh_strcasestr (rrule, "FREQ=YEARLY;INTERVAL=1")) { + if (nmh_strcasestr (rrule, "FREQ=YEARLY;INTERVAL=1") || + (nmh_strcasestr (rrule, "FREQ=YEARLY") && nmh_strcasestr(rrule, "INTERVAL") == NULL)) { struct tws *tws; const char *cp; int wday = -1, month = -1; @@ -313,9 +320,8 @@ rrule_clock (const char *rrule, const char *starttime, const char *zone, fail: if (clock == 0) { - admonish (NULL, - "Unsupported RRULE format: %s, assume local timezone", - rrule); + inform("Unsupported RRULE format: %s, assume local timezone, continuing...", + rrule); } return clock; @@ -351,10 +357,9 @@ format_datetime (tzdesc_t timezones, const contentline *node) { Form #2: DATE WITH UTC TIME */ if (parse_datetime (node->value, NULL, 0, &tws[0]) == OK) { return strdup (dasctime (&tws[0], 0)); - } else { - advise (NULL, "unable to parse datetime %s", node->value); - return NULL; } + inform("unable to parse datetime %s", node->value); + return NULL; } /* @@ -364,7 +369,7 @@ format_datetime (tzdesc_t timezones, const contentline *node) { /* Find the corresponding tzdesc. */ for (tz = timezones; dt_timezone && tz; tz = tz->next) { - /* Property parameter values are case insenstive (RFC 5545 + /* Property parameter values are case insensitive (RFC 5545 Sec. 2) and time zone identifiers are property parameters (RFC 5545 Sec. 3.8.2.4), though it would seem odd to use different case in the same file for identifiers that are @@ -375,7 +380,7 @@ format_datetime (tzdesc_t timezones, const contentline *node) { if (tz) { free(dt_timezone); } else { - advise (NULL, "did not find VTIMEZONE section for %s", dt_timezone); + inform("did not find VTIMEZONE section for %s", dt_timezone); free(dt_timezone); return NULL; } @@ -417,7 +422,7 @@ format_datetime (tzdesc_t timezones, const contentline *node) { } if (transition[0] < transition[1]) { - advise (NULL, "format_datetime() requires that daylight " + inform("format_datetime() requires that daylight " "saving time transition precede standard time " "transition"); return NULL; @@ -427,7 +432,7 @@ format_datetime (tzdesc_t timezones, const contentline *node) { 0, &tws[0]) == OK) { dt[0] = tws[0].tw_clock; } else { - advise (NULL, "unable to parse datetime %s", node->value); + inform("unable to parse datetime %s", node->value); return NULL; } @@ -440,7 +445,7 @@ format_datetime (tzdesc_t timezones, const contentline *node) { &tws[1]) == OK) { dt[1] = tws[1].tw_clock; } else { - advise (NULL, "unable to parse datetime %s", + inform("unable to parse datetime %s", node->value); return NULL; } @@ -452,7 +457,7 @@ format_datetime (tzdesc_t timezones, const contentline *node) { if (dst) { if (tz->daylight_params.start_dt > 0 && dt[dst] < tz->daylight_params.start_dt) { - advise (NULL, "date-time of %s is before VTIMEZONE start " + inform("date-time of %s is before VTIMEZONE start " "of %s", node->value, tz->daylight_params.dtstart); return NULL; @@ -460,7 +465,7 @@ format_datetime (tzdesc_t timezones, const contentline *node) { } else { if (tz->standard_params.start_dt > 0 && dt[dst] < tz->standard_params.start_dt) { - advise (NULL, "date-time of %s is before VTIMEZONE start " + inform("date-time of %s is before VTIMEZONE start " "of %s", node->value, tz->standard_params.dtstart); return NULL; @@ -468,12 +473,12 @@ format_datetime (tzdesc_t timezones, const contentline *node) { } } else { if (! tp_std) { - advise (NULL, "unsupported date-time format: %s", + inform("unsupported date-time format: %s", tz->standard_params.dtstart); return NULL; } if (! tp_dt) { - advise (NULL, "unsupported date-time format: %s", node->value); + inform("unsupported date-time format: %s", node->value); return NULL; } }