summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordana <dana@dana.is>2018-12-29 05:22:34 -0600
committerdana <dana@dana.is>2018-12-29 05:24:25 -0600
commit162c198aabcdbe3795d34142c4707649f60fe499 (patch)
tree609bf48c39b34c288be4b3580bd9d70d1d4e583a
parentf64cd71d442b0b7152131282dd7567be010edb78 (diff)
downloadzsh-162c198aabcdbe3795d34142c4707649f60fe499.tar.gz
zsh-162c198aabcdbe3795d34142c4707649f60fe499.zip
43953: Fix rounding/truncation error in %. time-format specifier
Also fixes an issue where %. couldn't be used more than once in a format string without strange results Tweaked very slightly per workers/43954
-rw-r--r--ChangeLog5
-rw-r--r--Src/utils.c21
-rw-r--r--Test/V09datetime.ztst16
3 files changed, 36 insertions, 6 deletions
diff --git a/ChangeLog b/ChangeLog
index 8f92c8e34..2e37557df 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2018-12-29 dana <dana@dana.is>
+
+ * 43953 (tweaked per 43954): Src/utils.c, Test/V09datetime.ztst:
+ Fix rounding/truncation error in %. time-format specifier
+
2018-12-24 dana <dana@dana.is>
* 43935 (tweaked): Src/Modules/datetime.c, Test/V09datetime.ztst:
diff --git a/Src/utils.c b/Src/utils.c
index e43a3cdb4..0969cef37 100644
--- a/Src/utils.c
+++ b/Src/utils.c
@@ -3334,19 +3334,28 @@ morefmt:
#endif
switch (*fmt++) {
case '.':
- if (ztrftimebuf(&bufsize, digs))
- return -1;
+ {
+ long fnsec = nsec;
if (digs > 9)
digs = 9;
+ if (ztrftimebuf(&bufsize, digs))
+ return -1;
if (digs < 9) {
int trunc;
- for (trunc = 8 - digs; trunc; trunc--)
- nsec /= 10;
- nsec = (nsec + 8) / 10;
+ long max = 100000000;
+ for (trunc = 8 - digs; trunc; trunc--) {
+ max /= 10;
+ fnsec /= 10;
+ }
+ max -= 1;
+ fnsec = (fnsec + 5) / 10;
+ if (fnsec > max)
+ fnsec = max;
}
- sprintf(buf, "%0*ld", digs, nsec);
+ sprintf(buf, "%0*ld", digs, fnsec);
buf += digs;
break;
+ }
case '\0':
/* Guard against premature end of string */
*buf++ = '%';
diff --git a/Test/V09datetime.ztst b/Test/V09datetime.ztst
index 2041d9b40..9f67ecec3 100644
--- a/Test/V09datetime.ztst
+++ b/Test/V09datetime.ztst
@@ -114,3 +114,19 @@
strftime -r '%Y' 2> /dev/null
1:-r timestring not optional
+
+ # This tests rounding up and the use of repeated %.s
+ strftime '%Y-%m-%d %H:%M:%S.%3..%3.' 1012615322 $(( 999_999 ))
+ # These test the ceiling on rounding up
+ for 1 in %. %1. %3. %6. %9. %12.; do
+ print -rn - "$1 "
+ strftime "%Y-%m-%d %H:%M:%S.$1" 1012615322 $(( 999_999_999 ))
+ done
+0:%. truncation
+>2002-02-02 02:02:02.001.001
+>%. 2002-02-02 02:02:02.999
+>%1. 2002-02-02 02:02:02.9
+>%3. 2002-02-02 02:02:02.999
+>%6. 2002-02-02 02:02:02.999999
+>%9. 2002-02-02 02:02:02.999999999
+>%12. 2002-02-02 02:02:02.999999999