From: David Levine Date: Sat, 23 Jan 2016 20:14:33 +0000 (-0500) Subject: mhical enhancement: If a datetime is missing the time, assume X-Git-Url: https://diplodocus.org/git/nmh/commitdiff_plain/f7416f95b570d8df280de899771db0f9f5f1b34e?ds=sidebyside;hp=905a55aa51624a993b54ebeee399cba2a32bcae6 mhical enhancement: If a datetime is missing the time, assume midnight. If there is no end datetime (DTEND) and the DTSTART doesn't contain a time, assume that the event is for the entire day. --- diff --git a/sbr/datetime.c b/sbr/datetime.c index 4e155855..4fb7bac0 100644 --- a/sbr/datetime.c +++ b/sbr/datetime.c @@ -62,7 +62,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, @@ -80,12 +83,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. */ diff --git a/test/mhical/test-mhical b/test/mhical/test-mhical index d3900e05..fb802508 100755 --- a/test/mhical/test-mhical +++ b/test/mhical/test-mhical @@ -93,7 +93,6 @@ EOF TZ=UTC mhical <"$MH_TEST_DIR/test1.ics" >"$MH_TEST_DIR/test1.txt" check "$expected" "$MH_TEST_DIR/test1.txt" -rm -f "$MH_TEST_DIR/test1.ics" # check display with 24 hour time format and -outfile @@ -120,7 +119,6 @@ EOF mhical -outfile "$MH_TEST_DIR/test1.txt" <"$MH_TEST_DIR/test1.ics" check "$expected" "$MH_TEST_DIR/test1.txt" -rm -f "$MH_TEST_DIR/test1.ics" # check display with 12 hour time format and -infile @@ -148,7 +146,6 @@ EOF mhical -form mhical.12hour -infile "$MH_TEST_DIR/test1.ics" \ >"$MH_TEST_DIR/test1.txt" check "$expected" "$MH_TEST_DIR/test1.txt" -rm -f "$MH_TEST_DIR/test1.ics" # check display with DST @@ -217,7 +214,6 @@ EOF TZ=EST mhical <"$MH_TEST_DIR/test1.ics" >"$MH_TEST_DIR/test1.txt" check "$expected" "$MH_TEST_DIR/test1.txt" -rm -f "$MH_TEST_DIR/test1.ics" # check timezone boundary at transition to daylight saving time @@ -269,7 +265,6 @@ EOF TZ=EST5EDT mhical -format '%(pretty{dtend})' \ -infile "$MH_TEST_DIR/test1.ics" -outfile "$MH_TEST_DIR/test1.txt" check "$expected" "$MH_TEST_DIR/test1.txt" -rm -f "$MH_TEST_DIR/test1.ics" # check timezone boundary at transition from daylight saving time @@ -319,7 +314,6 @@ EOF TZ=EST5EDT mhical -format '%(pretty{dtend})' \ -infile "$MH_TEST_DIR/test1.ics" -outfile "$MH_TEST_DIR/test1.txt" check "$expected" "$MH_TEST_DIR/test1.txt" -rm -f "$MH_TEST_DIR/test1.ics" printf 'Local-Mailbox: Requestee2 \n' >> "$MH" @@ -413,7 +407,6 @@ EOF mhical -reply accept <"$MH_TEST_DIR/test1.ics" | egrep -v '^DTSTAMP:' \ >"$MH_TEST_DIR/test1.txt" check "$expected" "$MH_TEST_DIR/test1.txt" -rm -f "$MH_TEST_DIR/test1.ics" # check accept of multiple vevent requests in single vcalendar cat >"$expected" <<'EOF' @@ -546,7 +539,6 @@ EOF mhical -reply accept <"$MH_TEST_DIR/test1.ics" | egrep -v '^DTSTAMP:' \ >"$MH_TEST_DIR/test1.txt" check "$expected" "$MH_TEST_DIR/test1.txt" -rm -f "$MH_TEST_DIR/test1.ics" # check decline of request @@ -608,7 +600,6 @@ EOF mhical -reply decline <"$MH_TEST_DIR/test1.ics" | egrep -v '^DTSTAMP:' \ >"$MH_TEST_DIR/test1.txt" check "$expected" "$MH_TEST_DIR/test1.txt" -rm -f "$MH_TEST_DIR/test1.ics" # check response of tentative to request, and -nocontenttype @@ -671,7 +662,6 @@ mhical -reply tentative -contenttype -nocontenttype \ -infile "$MH_TEST_DIR/test1.ics" | egrep -v '^DTSTAMP:' \ >"$MH_TEST_DIR/test1.txt" check "$expected" "$MH_TEST_DIR/test1.txt" -rm -f "$MH_TEST_DIR/test1.ics" # check cancel request, and -contenttype @@ -736,7 +726,6 @@ EOF mhical -cancel -contenttype <"$MH_TEST_DIR/test1.ics" | egrep -v '^DTSTAMP:' \ >"$MH_TEST_DIR/test1.txt" check "$expected" "$MH_TEST_DIR/test1.txt" -rm -f "$MH_TEST_DIR/test1.ics" # Check TZID name wrapped with quotes, this used to cause a segfault. @@ -770,6 +759,39 @@ END:VEVENT END:VCALENDAR EOF +TZ=UTC mhical <"$MH_TEST_DIR/test1.ics" >"$MH_TEST_DIR/test1.txt" +check "$expected" "$MH_TEST_DIR/test1.txt" + + +# Check start datetime without a time, and missing end datetime. +cat >"$expected" <<'EOF' +Method: PUBLISH +Summary: Test datetime without time +At: Wed, 30 Dec 2015 00:00 +To: Wed, 30 Dec 2015 23:59 +EOF + +cat >"$MH_TEST_DIR/test1.ics" <<'EOF' +BEGIN:VCALENDAR +VERSION:2.0 +PRODID:icalendar-ruby +CALSCALE:GREGORIAN +METHOD:PUBLISH +BEGIN:VEVENT +DTSTAMP:20151208T204350Z +UID:0123456789 +DTSTART;VALUE=DATE:20151230 +CLASS:PRIVATE +SUMMARY:Test datetime without time +BEGIN:VALARM +ACTION:DISPLAY +DESCRIPTION:REMINDER +TRIGGER;RELATED=START:-PT15M +END:VALARM +END:VEVENT +END:VCALENDAR +EOF + TZ=UTC mhical <"$MH_TEST_DIR/test1.ics" >"$MH_TEST_DIR/test1.txt" check "$expected" "$MH_TEST_DIR/test1.txt" rm -f "$MH_TEST_DIR/test1.ics" diff --git a/uip/mhical.c b/uip/mhical.c index 8ab305aa..324d4b63 100644 --- a/uip/mhical.c +++ b/uip/mhical.c @@ -652,6 +652,25 @@ display (FILE *file, contentline *clines, char *nfs) { if ((node = find_contentline (clines, "DTEND", 0)) && node->value) { char *datetime = format_datetime (timezones, node); c->c_text = datetime ? datetime : strdup(node->value); + } else if ((node = find_contentline (clines, "DTSTART", 0)) && + node->value) { + /* There is no DTEND. If there's a DTSTART, use it. If it + doesn't have a time, assume that the event is for the + entire day and append 23:59:59 to it so that it signifies + the end of the day. And assume local timezone. */ + if (strchr(node->value, 'T')) { + char * datetime = format_datetime (timezones, node); + c->c_text = datetime ? datetime : strdup(node->value); + } else { + char *datetime; + contentline node_copy; + + memcpy(&node_copy, node, sizeof node_copy); + node_copy.value = concat(node_copy.value, "T235959", NULL); + datetime = format_datetime (timezones, &node_copy); + c->c_text = datetime ? datetime : strdup(node_copy.value); + free(node_copy.value); + } } }