Skip to content

Commit b784840

Browse files
sgngitster
authored andcommitted
date.c: skip fractional second part of ISO-8601
git-commit(1) says ISO-8601 is one of our supported date format. ISO-8601 allows timestamps to have a fractional number of seconds. We represent time only in terms of whole seconds, so we never bothered parsing fractional seconds. However, it's better for us to parse and throw away the fractional part than to refuse to parse the timestamp at all. And refusing parsing fractional second part may confuse the parse to think fractional and timezone as day and month in this example: 2008-02-14 20:30:45.019-04:00 While doing this, make sure that we only interpret the number after the second and the dot as fractional when and only when the date is known, since only ISO-8601 allows the fractional part, and we've taught our users to interpret "12:34:56.7.days.ago" as a way to specify a time relative to current time. Reported-by: Brian M. Carlson <[email protected]> Helped-by: Junio C Hamano <[email protected]> Signed-off-by: Đoàn Trần Công Danh <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 4f89f4f commit b784840

File tree

3 files changed

+19
-1
lines changed

3 files changed

+19
-1
lines changed

Documentation/date-formats.txt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,10 @@ RFC 2822::
2020
ISO 8601::
2121
Time and date specified by the ISO 8601 standard, for example
2222
`2005-04-07T22:13:13`. The parser accepts a space instead of the
23-
`T` character as well.
23+
`T` character as well. Fractional parts of a second will be ignored,
24+
for example `2005-04-07T22:13:13.019` will be treated as
25+
`2005-04-07T22:13:13`
26+
2427
+
2528
NOTE: In addition, the date part is accepted in the following formats:
2629
`YYYY.MM.DD`, `MM/DD/YYYY` and `DD.MM.YYYY`.

date.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -553,6 +553,11 @@ static int set_time(long hour, long minute, long second, struct tm *tm)
553553
return -1;
554554
}
555555

556+
static int is_date_known(struct tm *tm)
557+
{
558+
return tm->tm_year != -1 && tm->tm_mon != -1 && tm->tm_mday != -1;
559+
}
560+
556561
static int match_multi_number(timestamp_t num, char c, const char *date,
557562
char *end, struct tm *tm, time_t now)
558563
{
@@ -571,6 +576,13 @@ static int match_multi_number(timestamp_t num, char c, const char *date,
571576
if (num3 < 0)
572577
num3 = 0;
573578
if (set_time(num, num2, num3, tm) == 0) {
579+
/*
580+
* If %H:%M:%S was just parsed followed by: .<num4>
581+
* Consider (& discard) it as fractional second
582+
* if %Y%m%d is parsed before.
583+
*/
584+
if (*end == '.' && isdigit(end[1]) && is_date_known(tm))
585+
strtol(end + 1, &end, 10);
574586
break;
575587
}
576588
return 0;

t/t0006-date.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ check_parse 2008-02 bad
8181
check_parse 2008-02-14 bad
8282
check_parse '2008-02-14 20:30:45' '2008-02-14 20:30:45 +0000'
8383
check_parse '2008-02-14 20:30:45 -0500' '2008-02-14 20:30:45 -0500'
84+
check_parse '2008.02.14 20:30:45 -0500' '2008-02-14 20:30:45 -0500'
85+
check_parse '2008-02-14 20:30:45.019-04:00' '2008-02-14 20:30:45 -0400'
8486
check_parse '2008-02-14 20:30:45 -0015' '2008-02-14 20:30:45 -0015'
8587
check_parse '2008-02-14 20:30:45 -5' '2008-02-14 20:30:45 +0000'
8688
check_parse '2008-02-14 20:30:45 -5:' '2008-02-14 20:30:45 +0000'
@@ -103,6 +105,7 @@ check_approxidate 5.seconds.ago '2009-08-30 19:19:55'
103105
check_approxidate 10.minutes.ago '2009-08-30 19:10:00'
104106
check_approxidate yesterday '2009-08-29 19:20:00'
105107
check_approxidate 3.days.ago '2009-08-27 19:20:00'
108+
check_approxidate '12:34:56.3.days.ago' '2009-08-27 12:34:56'
106109
check_approxidate 3.weeks.ago '2009-08-09 19:20:00'
107110
check_approxidate 3.months.ago '2009-05-30 19:20:00'
108111
check_approxidate 2.years.3.months.ago '2007-05-30 19:20:00'

0 commit comments

Comments
 (0)