From: Phil Hord <phil.hord@gmail.com>
To: git@vger.kernel.org
Cc: congdanhqx@gmail.com, plavarre@purestorage.com,
Phil Hord <phil.hord@gmail.com>
Subject: [PATCH] date.c: allow ISO 8601 reduced precision times
Date: Thu, 15 Dec 2022 19:36:39 -0800 [thread overview]
Message-ID: <20221216033638.2582956-1-phil.hord@gmail.com> (raw)
From: Phil Hord <phil.hord@gmail.com>
ISO 8601 permits "reduced precision" time representations to omit the
seconds value or both the minutes and the seconds values. The
abbreviate times could look like 17:45 or 1745 to omit the seconds,
or simply as 17 to omit both the minutes and the seconds.
parse_date_basic accepts the 17:45 format but it rejects the other two.
Fix it to accept 4-digit and 2-digit time values when they follow a
recognized date but no time has yet been parsed.
Add tests for these formats and some others, with and without colons.
Before this change:
$ test-tool date approxidate 2022-12-13T23:00 2022-12-13T2300 2022-12-13T23
2022-12-13T23:00 -> 2022-12-14 07:00:00 +0000
2022-12-13T2300 -> 2022-12-14 03:00:55 +0000
2022-12-13T23 -> 2022-12-14 03:00:55 +0000
After this change:
$ test-tool date approxidate 2022-12-13T23:00 2022-12-13T2300 2022-12-13T23
2022-12-13T23:00 -> 2022-12-14 07:00:00 +0000
2022-12-13T2300 -> 2022-12-14 07:00:00 +0000
2022-12-13T23 -> 2022-12-14 07:00:00 +0000
Note: ISO 8601 also allows reduced precision date strings such as
"2022-12" and "2022". This patch does not attempt to address these.
Reported-by: Pat LaVarre <plavarre@purestorage.com>
Signed-off-by: Phil Hord <phil.hord@gmail.com>
---
date.c | 22 +++++++++++++++++++++-
t/t0006-date.sh | 6 ++++++
2 files changed, 27 insertions(+), 1 deletion(-)
diff --git a/date.c b/date.c
index 53bd6a7932..b011b9d6b3 100644
--- a/date.c
+++ b/date.c
@@ -638,6 +638,18 @@ static inline int nodate(struct tm *tm)
tm->tm_sec) < 0;
}
+/*
+ * Have we filled in any part of the time yet?
+ * We just do a binary 'and' to see if the sign bit
+ * is set in all the values.
+ */
+static inline int notime(struct tm *tm)
+{
+ return (tm->tm_hour &
+ tm->tm_min &
+ tm->tm_sec) < 0;
+}
+
/*
* We've seen a digit. Time? Year? Date?
*/
@@ -689,7 +701,11 @@ static int match_digit(const char *date, struct tm *tm, int *offset, int *tm_gmt
/* 8 digits, compact style of ISO-8601's date: YYYYmmDD */
/* 6 digits, compact style of ISO-8601's time: HHMMSS */
- if (n == 8 || n == 6) {
+ /* 4 digits, compact style of ISO-8601's time: HHMM */
+ /* 2 digits, compact style of ISO-8601's time: HH */
+ if (n == 8 || n == 6 ||
+ (!nodate(tm) && notime(tm) &&
+ (n == 4 || n == 2))) {
unsigned int num1 = num / 10000;
unsigned int num2 = (num % 10000) / 100;
unsigned int num3 = num % 100;
@@ -698,6 +714,10 @@ static int match_digit(const char *date, struct tm *tm, int *offset, int *tm_gmt
else if (n == 6 && set_time(num1, num2, num3, tm) == 0 &&
*end == '.' && isdigit(end[1]))
strtoul(end + 1, &end, 10);
+ else if (n == 4)
+ set_time(num2, num3, 0, tm);
+ else if (n == 2)
+ set_time(num3, 0, 0, tm);
return end - date;
}
diff --git a/t/t0006-date.sh b/t/t0006-date.sh
index 2490162071..16fb0bf4bd 100755
--- a/t/t0006-date.sh
+++ b/t/t0006-date.sh
@@ -88,6 +88,12 @@ check_parse 2008-02-14 bad
check_parse '2008-02-14 20:30:45' '2008-02-14 20:30:45 +0000'
check_parse '2008-02-14 20:30:45 -0500' '2008-02-14 20:30:45 -0500'
check_parse '2008.02.14 20:30:45 -0500' '2008-02-14 20:30:45 -0500'
+check_parse '20080214T20:30:45' '2008-02-14 20:30:45 +0000'
+check_parse '20080214T20:30' '2008-02-14 20:30:00 +0000'
+check_parse '20080214T20' '2008-02-14 20:00:00 +0000'
+check_parse '20080214T203045' '2008-02-14 20:30:45 +0000'
+check_parse '20080214T2030' '2008-02-14 20:30:00 +0000'
+check_parse '20080214T20' '2008-02-14 20:00:00 +0000'
check_parse '20080214T203045-04:00' '2008-02-14 20:30:45 -0400'
check_parse '20080214T203045 -04:00' '2008-02-14 20:30:45 -0400'
check_parse '20080214T203045.019-04:00' '2008-02-14 20:30:45 -0400'
--
2.39.0.56.g57e2c6ebbe
next reply other threads:[~2022-12-16 3:38 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-12-16 3:36 Phil Hord [this message]
2022-12-16 4:23 ` [PATCH] date.c: allow ISO 8601 reduced precision times Junio C Hamano
2022-12-16 18:38 ` Phil Hord
2023-01-09 6:41 ` Phil Hord
2023-01-09 8:48 ` Junio C Hamano
2023-01-09 9:16 ` Junio C Hamano
2023-01-09 18:30 ` Phil Hord
2023-01-09 11:29 ` [PATCH] fixup! " Đoàn Trần Công Danh
2023-01-09 12:29 ` [PATCH] date.c: limit less precision ISO-8601 with its marker Đoàn Trần Công Danh
2023-01-09 18:57 ` Phil Hord
2023-01-11 0:10 ` [PATCH v2] date.c: allow ISO 8601 reduced precision times Đoàn Trần Công Danh
2023-01-13 19:50 ` Junio C Hamano
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20221216033638.2582956-1-phil.hord@gmail.com \
--to=phil.hord@gmail.com \
--cc=congdanhqx@gmail.com \
--cc=git@vger.kernel.org \
--cc=plavarre@purestorage.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).