[tz] [PROPOSED] zic now rounds to even
Paul Eggert
eggert at cs.ucla.edu
Mon Feb 5 05:12:34 UTC 2018
* NEWS, zic.8: Mention this.
* zic.c (gethms): Round to even instead of discarding fractional
seconds.
---
NEWS | 5 +++--
zic.8 | 4 +++-
zic.c | 18 ++++++++++++++----
3 files changed, 20 insertions(+), 7 deletions(-)
diff --git a/NEWS b/NEWS
index f00b29f..adc9814 100644
--- a/NEWS
+++ b/NEWS
@@ -45,8 +45,9 @@ Unreleased, experimental changes
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.
+ zic currently rounds these fractions to the nearest integer
+ (breaking ties to the even integer), the fractions 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 f1fc8e2..28e4bd6 100644
--- a/zic.8
+++ b/zic.8
@@ -267,8 +267,10 @@ 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
+currently rounds fractional seconds to the nearest integer
+(breaking ties to the even integer), the fractions may be useful
to other applications requiring greater precision.
+The source format does not specify any maximum 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 4965a10..6ad31f9 100644
--- a/zic.c
+++ b/zic.c
@@ -1197,7 +1197,8 @@ gethms(char const *string, char const *errstring, bool signable)
{
zic_t hh;
int sign, mm = 0, ss = 0;
- char hhx, mmx, ssx, xs;
+ char hhx, mmx, ssx, xr = '0', xs;
+ int tenths = 0;
bool ok = true;
if (string == NULL || *string == '\0')
@@ -1209,10 +1210,18 @@ gethms(char const *string, char const *errstring, bool signable)
++string;
} else sign = 1;
switch (sscanf(string,
- "%"SCNdZIC"%c%d%c%d%c%*1d%*[0123456789]%c",
- &hh, &hhx, &mm, &mmx, &ss, &ssx, &xs)) {
+ "%"SCNdZIC"%c%d%c%d%c%1d%*[0]%c%*[0123456789]%c",
+ &hh, &hhx, &mm, &mmx, &ss, &ssx, &tenths, &xr, &xs)) {
default: ok = false; break;
- case 6: ok &= ssx == '.'; /* fallthrough */
+ case 8:
+ ok = '0' <= xr && xr <= '9';
+ /* fallthrough */
+ case 7:
+ ok &= ssx == '.';
+ if (ok && noise)
+ warning(_("fractional seconds rejected by"
+ " pre-2018 versions of zic"));
+ /* fallthrough */
case 5: ok &= mmx == ':'; /* fallthrough */
case 3: ok &= hhx == ':'; /* fallthrough */
case 1: break;
@@ -1231,6 +1240,7 @@ gethms(char const *string, char const *errstring, bool signable)
error(_("time overflow"));
return 0;
}
+ ss += 5 + ((ss ^ 1) & (xr == '0')) <= tenths; /* Round to even. */
if (noise && (hh > HOURSPERDAY ||
(hh == HOURSPERDAY && (mm != 0 || ss != 0))))
warning(_("values over 24 hours not handled by pre-2007 versions of zic"));
--
2.7.4
More information about the tz
mailing list