Skip to content

Commit 36e4986

Browse files
torvaldsgitster
authored andcommitted
Further 'approxidate' improvements
The previous patch to improve approxidate got us to the point that a lot of the remaining annoyances were due to the 'strict' date handling running first, and deciding that it got a good enough date that the approximate date routines were never even invoked. For example, using a date string like 6AM, June 7, 2009 the strict date logic would be perfectly happy with the "June 7, 2009" part, and ignore the 6AM part that it didn't understand - resulting in the information getting dropped on the floor: 6AM, June 7, 2009 -> Sat Jun 6 00:00:00 2009 and the date being calculated as if it was midnight, and the '6AM' having confused the date routines into thinking about '6 June' rather than 'June 7' at 6AM (ie notice how the _day_ was wrong due to this, not just the time). So this makes the strict date routines a bit stricter, and requires that not just the date, but also the time, has actually been parsed. With that fix, and trivial extension of the approxidate routines, git now properly parses the date as 6AM, June 7, 2009 -> Sun Jun 7 06:00:00 2009 without dropping the fuzzy time ("6AM" or "noon" or any of the other non-strict time formats) on the floor. Signed-off-by: Linus Torvalds <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 9029055 commit 36e4986

File tree

1 file changed

+27
-5
lines changed

1 file changed

+27
-5
lines changed

date.c

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ time_t tm_to_time_t(const struct tm *tm)
2424
return -1;
2525
if (month < 2 || (year + 2) % 4)
2626
day--;
27+
if (tm->tm_hour < 0 || tm->tm_min < 0 || tm->tm_sec < 0)
28+
return -1;
2729
return (year * 365 + (year + 1) / 4 + mdays[month] + day) * 24*60*60UL +
2830
tm->tm_hour * 60*60 + tm->tm_min * 60 + tm->tm_sec;
2931
}
@@ -425,13 +427,19 @@ static int match_multi_number(unsigned long num, char c, const char *date, char
425427
return end - date;
426428
}
427429

428-
/* Have we filled in any part of the time/date yet? */
430+
/*
431+
* Have we filled in any part of the time/date yet?
432+
* We just do a binary 'and' to see if the sign bit
433+
* is set in all the values.
434+
*/
429435
static inline int nodate(struct tm *tm)
430436
{
431-
return tm->tm_year < 0 &&
432-
tm->tm_mon < 0 &&
433-
tm->tm_mday < 0 &&
434-
!(tm->tm_hour | tm->tm_min | tm->tm_sec);
437+
return (tm->tm_year &
438+
tm->tm_mon &
439+
tm->tm_mday &
440+
tm->tm_hour &
441+
tm->tm_min &
442+
tm->tm_sec) < 0;
435443
}
436444

437445
/*
@@ -580,6 +588,9 @@ int parse_date(const char *date, char *result, int maxlen)
580588
tm.tm_mon = -1;
581589
tm.tm_mday = -1;
582590
tm.tm_isdst = -1;
591+
tm.tm_hour = -1;
592+
tm.tm_min = -1;
593+
tm.tm_sec = -1;
583594
offset = -1;
584595
tm_gmt = 0;
585596

@@ -893,6 +904,17 @@ static void pending_number(struct tm *tm, int *num)
893904
*num = 0;
894905
if (tm->tm_mday < 0 && number < 32)
895906
tm->tm_mday = number;
907+
else if (tm->tm_mon < 0 && number < 13)
908+
tm->tm_mon = number-1;
909+
else if (tm->tm_year < 0) {
910+
if (number > 1969 && number < 2100)
911+
tm->tm_year = number - 1900;
912+
else if (number > 69 && number < 100)
913+
tm->tm_year = number;
914+
else if (number < 38)
915+
tm->tm_year = 100 + number;
916+
/* We screw up for number = 00 ? */
917+
}
896918
}
897919
}
898920

0 commit comments

Comments
 (0)