From 794dc7ca703ec2ce186997d2b48a90bebc04f9ba Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Wed, 31 Jan 2018 23:13:35 -0800 Subject: [PATCH] Add fractional seconds to data format * NEWS, zic.8: Mention this. * zic.c (gethms): Accept and ignore fractional seconds. Simplify by using just one call to sscanf instead of three. --- NEWS | 6 ++++++ zic.8 | 7 ++++++- zic.c | 21 +++++++++++++-------- 3 files changed, 25 insertions(+), 9 deletions(-) diff --git a/NEWS b/NEWS index c455f3c..ed7e7d3 100644 --- a/NEWS +++ b/NEWS @@ -4,6 +4,7 @@ Unreleased, experimental changes Briefly: Support zi parsers that mishandle negative DST offsets + Add fractional seconds to source data format. Changes to build procedure @@ -34,6 +35,11 @@ Unreleased, experimental changes Changes to code + zic now accepts fractional seconds in expressions like 00:19:32.13 + (the UT offset of the Netherlands from 1835 to 1937). Although + zic currently ignores these fractions, they may be useful to + applications requiring more precision in historical timestamps. + The code is a bit more portable to MS-Windows. (Thanks to Manuela Friedrich). diff --git a/zic.8 b/zic.8 index b4eface..f1fc8e2 100644 --- a/zic.8 +++ b/zic.8 @@ -251,10 +251,11 @@ Recognized forms include: .nf .in +.5i .sp -.ta \w'01:28:13\0\0'u +.ta \w'00:19:32.13\0\0'u 2 time in hours 2:00 time in hours and minutes 01:28:14 time in hours, minutes, and seconds +00:19:32.13 time with fractional seconds 15:00 24-hour format time (for times after noon) 260:00 260 hours after 00:00 \*-2:30 2.5 hours before 00:00 @@ -264,6 +265,10 @@ Recognized forms include: .sp where hour 0 is midnight at the start of the day, and hour 24 is midnight at the end of the day. +Although +.I zic +currently ignores any fractional seconds, the fractions may be useful +to other applications requiring greater precision. Any of these forms may be followed by the letter .B w if the given time is local diff --git a/zic.c b/zic.c index 55c83e9..4965a10 100644 --- a/zic.c +++ b/zic.c @@ -1196,8 +1196,9 @@ static zic_t gethms(char const *string, char const *errstring, bool signable) { zic_t hh; - int mm, ss, sign; - char xs; + int sign, mm = 0, ss = 0; + char hhx, mmx, ssx, xs; + bool ok = true; if (string == NULL || *string == '\0') return 0; @@ -1207,12 +1208,16 @@ gethms(char const *string, char const *errstring, bool signable) sign = -1; ++string; } else sign = 1; - if (sscanf(string, "%"SCNdZIC"%c", &hh, &xs) == 1) - mm = ss = 0; - else if (sscanf(string, "%"SCNdZIC":%d%c", &hh, &mm, &xs) == 2) - ss = 0; - else if (sscanf(string, "%"SCNdZIC":%d:%d%c", &hh, &mm, &ss, &xs) - != 3) { + switch (sscanf(string, + "%"SCNdZIC"%c%d%c%d%c%*1d%*[0123456789]%c", + &hh, &hhx, &mm, &mmx, &ss, &ssx, &xs)) { + default: ok = false; break; + case 6: ok &= ssx == '.'; /* fallthrough */ + case 5: ok &= mmx == ':'; /* fallthrough */ + case 3: ok &= hhx == ':'; /* fallthrough */ + case 1: break; + } + if (!ok) { error("%s", errstring); return 0; } -- 2.7.4