git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
* [PATCH] date.c: allow ISO 8601 reduced precision times
@ 2022-12-16  3:36 Phil Hord
  2022-12-16  4:23 ` Junio C Hamano
  2023-01-11  0:10 ` [PATCH v2] date.c: allow ISO 8601 reduced precision times Đoàn Trần Công Danh
  0 siblings, 2 replies; 12+ messages in thread
From: Phil Hord @ 2022-12-16  3:36 UTC (permalink / raw)
  To: git; +Cc: congdanhqx, plavarre, Phil Hord

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


^ permalink raw reply related	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2023-01-13 19:51 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-12-16  3:36 [PATCH] date.c: allow ISO 8601 reduced precision times Phil Hord
2022-12-16  4:23 ` 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

Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

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 read-only IMAP folder(s) and NNTP newsgroup(s).