[Toybox] [PATCH v2] xparsedate properly detect whether format contains seconds.
HONG Yifan
elsk at google.com
Tue Sep 17 15:08:40 PDT 2024
The code below with "If format didn't already specify seconds, grab
seconds" detects whether the format contains seconds by relying on the
index of the format (with an i>2 predicate). However, the format
"%a %b %e %H:%M:%S %Z %Y" does not end with seconds, so we shouldn't
parse fraction of seconds here. On the other hand, the format
"%H:%M:%S" ends with seconds, so we should parse fraction of seconds
there.
Add a test for it; the test uses a >60 number for fraction of seconds
to trigger the bug before the fix. Without the fix, "12:34:56.777" are
recognized as "12:34:77", which is an invalid time.
Fixes: d1a446687a9c
("xparsedate: support default date(1) output format.")
---
lib/xwrap.c | 3 ++-
tests/date.test | 3 +++
2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/lib/xwrap.c b/lib/xwrap.c
index d07f355a..e5b35bb7 100644
--- a/lib/xwrap.c
+++ b/lib/xwrap.c
@@ -1025,8 +1025,9 @@ void xparsedate(char *str, time_t *t, unsigned *nano, int endian)
// Formats with seconds come first. Posix can't agree on whether 12 digits
// has year before (touch -t) or year after (date), so support both.
char *s = str, *p, *oldtz = 0, *formats[] = {"%Y-%m-%d %T", "%Y-%m-%dT%T",
+ "%H:%M:%S",
"%a %b %e %H:%M:%S %Z %Y", // date(1) output format in POSIX/C locale.
- "%H:%M:%S", "%Y-%m-%d %H:%M", "%Y-%m-%d", "%H:%M", "%m%d%H%M",
+ "%Y-%m-%d %H:%M", "%Y-%m-%d", "%H:%M", "%m%d%H%M",
endian ? "%m%d%H%M%y" : "%y%m%d%H%M",
endian ? "%m%d%H%M%C%y" : "%C%y%m%d%H%M"};
diff --git a/tests/date.test b/tests/date.test
index 9777edb3..3ec2659e 100644
--- a/tests/date.test
+++ b/tests/date.test
@@ -42,6 +42,9 @@ testing "Unix time missing @" "TZ=$tz date 1438053157 2>/dev/null || echo no" \
testing "-d 12:34" 'TZ=UTC date -d 12:34 | grep -q " 12:34:00 UTC $this_year" && echo OK' "OK\n" "" ""
testing "-d 12:34:56" 'TZ=UTC date -d 12:34:56 | grep -q " 12:34:56 UTC $this_year" && echo OK' "OK\n" "" ""
+# Test fraction
+testing "-d 12:34:56.777" 'date -d 12:34:56.777 +%H:%M:%S.%3N | grep -q "12:34:56.777" && echo OK' "OK\n" "" ""
+
# Test the %N extension to srtftime(3) format strings.
testing "%N" "touch -d 2012-01-23T12:34:56.123456789 f && date -r f +%Y%m%d-%H%M%S.%N" "20120123-123456.123456789\n" "" ""
testing "%1N" "touch -d 2012-01-23T12:34:56.123456789 f && date -r f +%Y%m%d-%H%M%S.%1N" "20120123-123456.1\n" "" ""
--
2.46.0.662.g92d0881bb0-goog
More information about the Toybox
mailing list