Merge branch 'ta/approxidate-noon-fix' into next

"Friday noon" asked in the morning on Sunday was parsed to be one
day before the specified time, which has been corrected.

* ta/approxidate-noon-fix:
  approxidate: use deferred mday adjustments for "specials"
  approxidate: make "specials" respect fixed day-of-month
  t0006: add support for approxidate test date adjustment
  approxidate: make "today" wrap to midnight
This commit is contained in:
Junio C Hamano
2026-05-25 09:41:08 +09:00
3 changed files with 81 additions and 12 deletions

View File

@@ -23,7 +23,8 @@ ordering and formatting options, such as `--reverse`.
`--since=<date>`::
`--after=<date>`::
Show commits more recent than _<date>_.
Show commits more recent than _<date>_. As a special case,
'today' means the last midnight.
`--since-as-filter=<date>`::
Show all commits more recent than _<date>_. This visits

46
date.c
View File

@@ -1071,13 +1071,22 @@ void datestamp(struct strbuf *out)
/*
* Relative time update (eg "2 days ago"). If we haven't set the time
* yet, we need to set it from current time.
*
* The tm->tm_mday field has an additional logic of using negative values
* for date adjustments: -2 means yesterday and -3 the day before that,
* and so on. The idea is to deref such adjustments until we are sure
* there's no explicit mday specification in the approxidate string.
*/
static time_t update_tm(struct tm *tm, struct tm *now, time_t sec)
{
time_t n;
if (tm->tm_mday < 0)
if (tm->tm_mday < 0) {
int offset = tm->tm_mday + 1;
if (sec == 0 && offset < 0)
sec = -offset * 24*60*60;
tm->tm_mday = now->tm_mday;
}
if (tm->tm_mon < 0)
tm->tm_mon = now->tm_mon;
if (tm->tm_year < 0) {
@@ -1127,34 +1136,39 @@ static void date_now(struct tm *tm, struct tm *now, int *num)
static void date_yesterday(struct tm *tm, struct tm *now, int *num)
{
*num = 0;
tm->tm_mday = -1;
update_tm(tm, now, 24*60*60);
}
static void date_time(struct tm *tm, struct tm *now, int hour)
static void date_time(struct tm *tm, int hour)
{
if (tm->tm_hour < hour)
update_tm(tm, now, 24*60*60);
/*
* If we do not yet have a specified day, we'll use the most recent
* version of "hour" relative to now. But that may be yesterday.
*/
if (tm->tm_mday < 0 && tm->tm_hour < hour)
tm->tm_mday = -2; /* eventually handled by update_tm() */
tm->tm_hour = hour;
tm->tm_min = 0;
tm->tm_sec = 0;
}
static void date_midnight(struct tm *tm, struct tm *now, int *num)
static void date_midnight(struct tm *tm, struct tm *now UNUSED, int *num)
{
pending_number(tm, num);
date_time(tm, now, 0);
date_time(tm, 0);
}
static void date_noon(struct tm *tm, struct tm *now, int *num)
static void date_noon(struct tm *tm, struct tm *now UNUSED, int *num)
{
pending_number(tm, num);
date_time(tm, now, 12);
date_time(tm, 12);
}
static void date_tea(struct tm *tm, struct tm *now, int *num)
static void date_tea(struct tm *tm, struct tm *now UNUSED, int *num)
{
pending_number(tm, num);
date_time(tm, now, 17);
date_time(tm, 17);
}
static void date_pm(struct tm *tm, struct tm *now UNUSED, int *num)
@@ -1192,6 +1206,17 @@ static void date_never(struct tm *tm, struct tm *now UNUSED, int *num)
*num = 0;
}
static void date_today(struct tm *tm, struct tm *now, int *num)
{
if (tm->tm_hour == now->tm_hour &&
tm->tm_min == now->tm_min &&
tm->tm_sec == now->tm_sec)
date_time(tm, 0);
*num = 0;
tm->tm_mday = -1;
update_tm(tm, now, 0);
}
static const struct special {
const char *name;
void (*fn)(struct tm *, struct tm *, int *);
@@ -1204,6 +1229,7 @@ static const struct special {
{ "AM", date_am },
{ "never", date_never },
{ "now", date_now },
{ "today", date_today },
{ NULL }
};

View File

@@ -155,15 +155,45 @@ check_parse '2100-00-00 00:00:00 -11' bad
check_parse '2100-00-00 00:00:00 +11' bad
REQUIRE_64BIT_TIME=
add_time_offset() {
case "$3" in
hours)
unit=$(( 60*60 ))
;;
days)
unit=$(( 24*60*60 ))
;;
esac
offset=$(( $2 * unit ))
echo $(( $1 + offset ))
}
check_approxidate() {
old_date=$GIT_TEST_DATE_NOW
if test "$3" = "failure"
then
expection="$3"
else
expection=${4:-success}
offset="$3"
fi
if test -n "$offset"
then
GIT_TEST_DATE_NOW=$(add_time_offset $old_date $offset)
caption="$1; offset $offset"
else
caption=$1
fi
echo "$1 -> $2 +0000" >expect
test_expect_${3:-success} "parse approxidate ($1)" "
test_expect_$expection "parse approxidate ($caption)" "
test-tool date approxidate '$1' >actual &&
test_cmp expect actual
"
GIT_TEST_DATE_NOW=$old_date
}
check_approxidate now '2009-08-30 19:20:00'
check_approxidate today '2009-08-30 00:00:00'
check_approxidate '5 seconds ago' '2009-08-30 19:19:55'
check_approxidate 5.seconds.ago '2009-08-30 19:19:55'
check_approxidate 10.minutes.ago '2009-08-30 19:10:00'
@@ -179,14 +209,26 @@ check_approxidate '6pm yesterday' '2009-08-29 18:00:00'
check_approxidate '3:00' '2009-08-30 03:00:00'
check_approxidate '15:00' '2009-08-30 15:00:00'
check_approxidate 'noon today' '2009-08-30 12:00:00'
check_approxidate 'today at noon' '2009-08-30 12:00:00' '-12 hours'
check_approxidate 'noon today' '2009-09-01 12:00:00' '+36 hours'
check_approxidate 'noon yesterday' '2009-08-29 12:00:00'
check_approxidate 'noon yesterday' '2009-08-29 12:00:00' '-12 hours'
check_approxidate 'last Friday at noon' '2009-08-28 12:00:00'
check_approxidate 'last Friday at noon' '2009-08-28 12:00:00' '-12 hours'
check_approxidate 'tea last saturday' '2009-08-29 17:00:00'
check_approxidate 'tea last saturday' '2009-08-29 17:00:00' '-12 hours'
check_approxidate 'January 5th noon pm' '2009-01-05 12:00:00'
check_approxidate 'January 5th noon pm' '2009-01-05 12:00:00' '-12 hours'
check_approxidate 'January 5th today pm' '2009-01-30 12:00:00'
check_approxidate '10am noon' '2009-08-29 12:00:00'
check_approxidate 'January 5th yesterday' '2009-01-29 19:20:00'
check_approxidate 'January 5th yesterday' '2008-12-31 19:20:00' '+2 days'
check_approxidate 'last tuesday' '2009-08-25 19:20:00'
check_approxidate 'July 5th' '2009-07-05 19:20:00'
check_approxidate '06/05/2009' '2009-06-05 19:20:00'
check_approxidate '06.05.2009' '2009-05-06 19:20:00'
check_approxidate 'Jan 5 today' '2009-01-30 00:00:00'
check_approxidate 'Jun 6, 5AM' '2009-06-06 05:00:00'
check_approxidate '5AM Jun 6' '2009-06-06 05:00:00'