Skip to content

Commit c27cc94

Browse files
peffgitster
authored andcommitted
approxidate: handle pending number for "specials"
The approxidate parser has a table of special keywords like "yesterday", "noon", "pm", etc. Some of these, like "pm", do the right thing if we've recently seen a number: "3pm" is what you'd think. However, most of them do not look at or modify the pending-number flag at all, which means a number may "jump" across a significant keyword and be used unexpectedly. For example, when parsing: January 5th noon pm we'd connect the "5" to "pm", and ignore it as a day-of-month. This is obviously a bit silly, as "noon" already implies "pm". And other mis-parsed things are generally as silly ("January 5th noon, years ago" would connect the 5 to "years", but probably nobody would type that). However, the fix is simple: when we see a keyword like "noon", we should flush the pending number (as we would if we hit another number, or the end of the string). In a few of the specials that actually modify the day, we can simply throw away the number (saying "Jan 5 yesterday" should not respect the number at all). Note that we have to either move or forward-declare the static pending_number() to make it accessible to these functions; this patch moves it. Signed-off-by: Jeff King <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent b4cfcde commit c27cc94

File tree

2 files changed

+34
-27
lines changed

2 files changed

+34
-27
lines changed

date.c

Lines changed: 33 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -887,13 +887,42 @@ static time_t update_tm(struct tm *tm, struct tm *now, time_t sec)
887887
return n;
888888
}
889889

890+
/*
891+
* Do we have a pending number at the end, or when
892+
* we see a new one? Let's assume it's a month day,
893+
* as in "Dec 6, 1992"
894+
*/
895+
static void pending_number(struct tm *tm, int *num)
896+
{
897+
int number = *num;
898+
899+
if (number) {
900+
*num = 0;
901+
if (tm->tm_mday < 0 && number < 32)
902+
tm->tm_mday = number;
903+
else if (tm->tm_mon < 0 && number < 13)
904+
tm->tm_mon = number-1;
905+
else if (tm->tm_year < 0) {
906+
if (number > 1969 && number < 2100)
907+
tm->tm_year = number - 1900;
908+
else if (number > 69 && number < 100)
909+
tm->tm_year = number;
910+
else if (number < 38)
911+
tm->tm_year = 100 + number;
912+
/* We screw up for number = 00 ? */
913+
}
914+
}
915+
}
916+
890917
static void date_now(struct tm *tm, struct tm *now, int *num)
891918
{
919+
*num = 0;
892920
update_tm(tm, now, 0);
893921
}
894922

895923
static void date_yesterday(struct tm *tm, struct tm *now, int *num)
896924
{
925+
*num = 0;
897926
update_tm(tm, now, 24*60*60);
898927
}
899928

@@ -908,16 +937,19 @@ static void date_time(struct tm *tm, struct tm *now, int hour)
908937

909938
static void date_midnight(struct tm *tm, struct tm *now, int *num)
910939
{
940+
pending_number(tm, num);
911941
date_time(tm, now, 0);
912942
}
913943

914944
static void date_noon(struct tm *tm, struct tm *now, int *num)
915945
{
946+
pending_number(tm, num);
916947
date_time(tm, now, 12);
917948
}
918949

919950
static void date_tea(struct tm *tm, struct tm *now, int *num)
920951
{
952+
pending_number(tm, num);
921953
date_time(tm, now, 17);
922954
}
923955

@@ -953,6 +985,7 @@ static void date_never(struct tm *tm, struct tm *now, int *num)
953985
{
954986
time_t n = 0;
955987
localtime_r(&n, tm);
988+
*num = 0;
956989
}
957990

958991
static const struct special {
@@ -1110,33 +1143,6 @@ static const char *approxidate_digit(const char *date, struct tm *tm, int *num,
11101143
return end;
11111144
}
11121145

1113-
/*
1114-
* Do we have a pending number at the end, or when
1115-
* we see a new one? Let's assume it's a month day,
1116-
* as in "Dec 6, 1992"
1117-
*/
1118-
static void pending_number(struct tm *tm, int *num)
1119-
{
1120-
int number = *num;
1121-
1122-
if (number) {
1123-
*num = 0;
1124-
if (tm->tm_mday < 0 && number < 32)
1125-
tm->tm_mday = number;
1126-
else if (tm->tm_mon < 0 && number < 13)
1127-
tm->tm_mon = number-1;
1128-
else if (tm->tm_year < 0) {
1129-
if (number > 1969 && number < 2100)
1130-
tm->tm_year = number - 1900;
1131-
else if (number > 69 && number < 100)
1132-
tm->tm_year = number;
1133-
else if (number < 38)
1134-
tm->tm_year = 100 + number;
1135-
/* We screw up for number = 00 ? */
1136-
}
1137-
}
1138-
}
1139-
11401146
static timestamp_t approxidate_str(const char *date,
11411147
const struct timeval *tv,
11421148
int *error_ret)

t/t0006-date.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ check_approxidate '3:00' '2009-08-30 03:00:00'
113113
check_approxidate '15:00' '2009-08-30 15:00:00'
114114
check_approxidate 'noon today' '2009-08-30 12:00:00'
115115
check_approxidate 'noon yesterday' '2009-08-29 12:00:00'
116+
check_approxidate 'January 5th noon pm' '2009-01-05 12:00:00'
116117

117118
check_approxidate 'last tuesday' '2009-08-25 19:20:00'
118119
check_approxidate 'July 5th' '2009-07-05 19:20:00'

0 commit comments

Comments
 (0)