All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/2] approxidate: tweak special date formats
@ 2025-03-18 18:01 Tuomas Ahola
  2025-03-18 18:02 ` [PATCH 1/2] approxidate: make "specials" respect fixed day-of-month Tuomas Ahola
                   ` (2 more replies)
  0 siblings, 3 replies; 23+ messages in thread
From: Tuomas Ahola @ 2025-03-18 18:01 UTC (permalink / raw)
  To: git; +Cc: Tuomas Ahola

I made a couple of somewhat hacky fixes in approxidate special date
formats after noticing that some tests succeeded only because of the
specified test time which happened to be too late to spot some
irregularities.

Thanks a lot in advance!

Tuomas Ahola (2):
  approxidate: make "specials" respect fixed day-of-month
  approxidate: overwrite tm_mday for `now` and `yesterday`

 date.c          | 5 ++++-
 t/t0006-date.sh | 9 ++++++---
 2 files changed, 10 insertions(+), 4 deletions(-)


base-commit: 683c54c999c301c2cd6f715c411407c413b1d84e
-- 
2.30.2


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

* [PATCH 1/2] approxidate: make "specials" respect fixed day-of-month
  2025-03-18 18:01 [PATCH 0/2] approxidate: tweak special date formats Tuomas Ahola
@ 2025-03-18 18:02 ` Tuomas Ahola
  2025-04-04  8:19   ` Jeff King
  2025-03-18 18:02 ` [PATCH 2/2] approxidate: overwrite tm_mday for `now` and `yesterday` Tuomas Ahola
  2026-05-12 14:54 ` [PATCH v2 0/3] approxidate: tweak special date formats Tuomas Ahola
  2 siblings, 1 reply; 23+ messages in thread
From: Tuomas Ahola @ 2025-03-18 18:02 UTC (permalink / raw)
  To: git; +Cc: Tuomas Ahola

The behaviour of noon and tea depends on the current time even when
the date is given.  In other words, "last Friday tea" is dated to
Thursday if the command is run before 17 pm.

This can be fixed by checking whether tm->tm_mday already holds a
determined value and tested by setting current time before 12 or 17 pm
for noon and tea respectively.

Signed-off-by: Tuomas Ahola <taahol@utu.fi>
---
 date.c          | 2 +-
 t/t0006-date.sh | 5 ++++-
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/date.c b/date.c
index 17a95077cf..482a2f8c99 100644
--- a/date.c
+++ b/date.c
@@ -1133,7 +1133,7 @@ static void date_yesterday(struct tm *tm, struct tm *now, int *num)
 static void date_time(struct tm *tm, struct tm *now, int hour)
 {
 	if (tm->tm_hour < hour)
-		update_tm(tm, now, 24*60*60);
+		update_tm(tm, now, tm->tm_mday < 0 ? 24*60*60 : 0);
 	tm->tm_hour = hour;
 	tm->tm_min = 0;
 	tm->tm_sec = 0;
diff --git a/t/t0006-date.sh b/t/t0006-date.sh
index 53ced36df4..5db4b23e0b 100755
--- a/t/t0006-date.sh
+++ b/t/t0006-date.sh
@@ -180,7 +180,10 @@ 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 'noon yesterday' '2009-08-29 12:00:00'
-check_approxidate 'January 5th noon pm' '2009-01-05 12:00:00'
+(
+	GIT_TEST_DATE_NOW=$(($GIT_TEST_DATE_NOW-12*60*60)); export GIT_TEST_DATE_NOW
+	check_approxidate 'January 5th noon pm' '2009-01-05 12:00:00'
+)
 check_approxidate '10am noon' '2009-08-29 12:00:00'
 
 check_approxidate 'last tuesday' '2009-08-25 19:20:00'
-- 
2.30.2


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

* [PATCH 2/2] approxidate: overwrite tm_mday for `now` and `yesterday`
  2025-03-18 18:01 [PATCH 0/2] approxidate: tweak special date formats Tuomas Ahola
  2025-03-18 18:02 ` [PATCH 1/2] approxidate: make "specials" respect fixed day-of-month Tuomas Ahola
@ 2025-03-18 18:02 ` Tuomas Ahola
  2025-04-04  8:40   ` Jeff King
  2026-05-12 14:54 ` [PATCH v2 0/3] approxidate: tweak special date formats Tuomas Ahola
  2 siblings, 1 reply; 23+ messages in thread
From: Tuomas Ahola @ 2025-03-18 18:02 UTC (permalink / raw)
  To: git; +Cc: Tuomas Ahola

Date specifications now (or today) and yesterday should refer to
actual current or previous day.  Especially "noon today" or "noon
yesterday" should override the usual logic of using the first previous
noon depending on the current time.

Signed-off-by: Tuomas Ahola <taahol@utu.fi>
---
 date.c          | 3 +++
 t/t0006-date.sh | 4 ++--
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/date.c b/date.c
index 482a2f8c99..2a8a942d64 100644
--- a/date.c
+++ b/date.c
@@ -1121,12 +1121,14 @@ static void pending_number(struct tm *tm, int *num)
 static void date_now(struct tm *tm, struct tm *now, int *num)
 {
 	*num = 0;
+	tm->tm_mday = -1;
 	update_tm(tm, now, 0);
 }
 
 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);
 }
 
@@ -1204,6 +1206,7 @@ static const struct special {
 	{ "AM", date_am },
 	{ "never", date_never },
 	{ "now", date_now },
+	{ "today", date_now },
 	{ NULL }
 };
 
diff --git a/t/t0006-date.sh b/t/t0006-date.sh
index 5db4b23e0b..6ad931dfb3 100755
--- a/t/t0006-date.sh
+++ b/t/t0006-date.sh
@@ -178,10 +178,10 @@ check_approxidate '6am yesterday' '2009-08-29 06:00:00'
 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 'noon yesterday' '2009-08-29 12:00:00'
 (
 	GIT_TEST_DATE_NOW=$(($GIT_TEST_DATE_NOW-12*60*60)); export GIT_TEST_DATE_NOW
+	check_approxidate 'noon today' '2009-08-30 12:00:00'
+	check_approxidate 'noon yesterday' '2009-08-29 12:00:00'
 	check_approxidate 'January 5th noon pm' '2009-01-05 12:00:00'
 )
 check_approxidate '10am noon' '2009-08-29 12:00:00'
-- 
2.30.2


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

* Re: [PATCH 1/2] approxidate: make "specials" respect fixed day-of-month
  2025-03-18 18:02 ` [PATCH 1/2] approxidate: make "specials" respect fixed day-of-month Tuomas Ahola
@ 2025-04-04  8:19   ` Jeff King
  0 siblings, 0 replies; 23+ messages in thread
From: Jeff King @ 2025-04-04  8:19 UTC (permalink / raw)
  To: Tuomas Ahola; +Cc: git

On Tue, Mar 18, 2025 at 08:02:00PM +0200, Tuomas Ahola wrote:

> The behaviour of noon and tea depends on the current time even when
> the date is given.  In other words, "last Friday tea" is dated to
> Thursday if the command is run before 17 pm.

Knowing what approxidate's code is like, I'm not too surprised we'd have
corner cases like this. ;)

> This can be fixed by checking whether tm->tm_mday already holds a
> determined value and tested by setting current time before 12 or 17 pm
> for noon and tea respectively.

That makes sense for "last Friday tea", but should "tea last Friday" or
"noon last Friday" work, too? I suspect it plays quite badly with
approxidate's left-to-right parsing, so it might not be worth crossing
that bridge.

> --- a/date.c
> +++ b/date.c
> @@ -1133,7 +1133,7 @@ static void date_yesterday(struct tm *tm, struct tm *now, int *num)
>  static void date_time(struct tm *tm, struct tm *now, int hour)
>  {
>  	if (tm->tm_hour < hour)
> -		update_tm(tm, now, 24*60*60);
> +		update_tm(tm, now, tm->tm_mday < 0 ? 24*60*60 : 0);
>  	tm->tm_hour = hour;
>  	tm->tm_min = 0;
>  	tm->tm_sec = 0;

My reading of that conditional is "if the time computed so far is before
the specified hour, then go back a day to yesterday's version of it". So
"noon" would be yesterday's noon if it is only 11am.

But if we already have a date, I'd think we would skip that logic
entirely. I.e., do we need to call update_tm() at all? Certainly in your
patch we'd pass 0, which would mean no adjustment. Do we need any other
parts of update_tm()? It looks like it fills the month, day, and year
from the "now" struct if they aren't already set, but presumably they'd
all be set together (and if they're not, then that raises even more
questions about whether just checking tm_mday is correct in your patch).

So it seems like:

  /*
   * 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)
	update_tm(tm, now, 24*60*60);

would be equivalent and is IMHO a bit easier to understand.

> diff --git a/t/t0006-date.sh b/t/t0006-date.sh
> index 53ced36df4..5db4b23e0b 100755
> --- a/t/t0006-date.sh
> +++ b/t/t0006-date.sh
> @@ -180,7 +180,10 @@ 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 'noon yesterday' '2009-08-29 12:00:00'
> -check_approxidate 'January 5th noon pm' '2009-01-05 12:00:00'
> +(
> +	GIT_TEST_DATE_NOW=$(($GIT_TEST_DATE_NOW-12*60*60)); export GIT_TEST_DATE_NOW
> +	check_approxidate 'January 5th noon pm' '2009-01-05 12:00:00'
> +)
>  check_approxidate '10am noon' '2009-08-29 12:00:00'

I'm glad there's a test, but two comments. One, wouldn't we still want
to keep the existing test to make sure that we continue to do the right
thing when the "now" hour is after noon?

And two, I'm pretty sure this sub-shell will confuse the test harness,
because you're running test_expect_success inside it. So any variable
updates won't be seen by the parent shell, and I wouldn't be surprised
if attempts to exit from "-i", etc, are broken.

Hmm, yeah, running the test yields this output:

  ok 110 - parse approxidate (noon yesterday)
  ok 111 - parse approxidate (January 5th noon pm)
  ok 111 - parse approxidate (10am noon)
  ok 112 - parse approxidate (last tuesday)

because the update of the test counter is lost in the sub-shell.

I don't think there's a trivial solution. You can't do a one-shot
variable-set like:

  TEST_DATE_NOW=... check_approxidate ...

because the behavior of that construct varies between shells. So you
have to either add support for an extra parameter to check_approxidate,
or just save and restore like:

  old_date=$GIT_TEST_DATE_NOW
  GIT_TEST_DATE_NOW=$((GIT_TEST_DATE_NOW-12*60*60))
  check_approxidate ...
  GIT_TEST_DATE_NOW=$old_date

It would be nice to add a comment there, too, on what the 12-hour
parameter means and what we expect. Maybe something like:

  # The "now" date is usually at 1900 in the evening. Roll it back to
  # the morning so that it is before the hour of named times like
  # "noon" and "tea".

-Peff

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

* Re: [PATCH 2/2] approxidate: overwrite tm_mday for `now` and `yesterday`
  2025-03-18 18:02 ` [PATCH 2/2] approxidate: overwrite tm_mday for `now` and `yesterday` Tuomas Ahola
@ 2025-04-04  8:40   ` Jeff King
  0 siblings, 0 replies; 23+ messages in thread
From: Jeff King @ 2025-04-04  8:40 UTC (permalink / raw)
  To: Tuomas Ahola; +Cc: git

On Tue, Mar 18, 2025 at 08:02:01PM +0200, Tuomas Ahola wrote:

> Date specifications now (or today) and yesterday should refer to
> actual current or previous day.  Especially "noon today" or "noon
> yesterday" should override the usual logic of using the first previous
> noon depending on the current time.

OK. So if I understand the issue correctly, it is that saying "noon"
sets the day field of the "struct tm", and then "today" or "yesterday"
won't override that, because update_tm() tries not to touch those fields
if they're already set.

This presumably works for "10am yesterday" because "10am" just sets the
time, and never the date (though I didn't check).

> diff --git a/date.c b/date.c
> index 482a2f8c99..2a8a942d64 100644
> --- a/date.c
> +++ b/date.c
> @@ -1121,12 +1121,14 @@ static void pending_number(struct tm *tm, int *num)
>  static void date_now(struct tm *tm, struct tm *now, int *num)
>  {
>  	*num = 0;
> +	tm->tm_mday = -1;
>  	update_tm(tm, now, 0);
>  }

So OK, this approach makes sense: throw out the old date we computed so
that update_tm() can use today's.

But is resetting tm_mday enough? If we previously set tm_mon, then
update_tm() won't override that, but it would need to follow along with
tm_mday, wouldn't it?

So if it is the morning of April 2nd, that will work fine, since
yesterday and today have the same month. And it seems to (this is with
your patch):

  $ GIT_TEST_DATE_NOW=$(date --date='2025-04-02 11:00' +%s) \
    t/helper/test-tool date approxidate 'noon today'
  noon today -> 2025-04-02 16:00:00 +0000

but if we try the same thing on the 1st:

  $ GIT_TEST_DATE_NOW=$(date --date='2025-04-01 11:00' +%s) \
    t/helper/test-tool date approxidate 'noon today'
  noon today -> 2025-03-01 16:00:00 +0000

Oops, we went back a month. And presumably the same thing would happen
with the year on Jan 1st.

Interestingly, since we are passing "0" to update_tm() as its
adjustment, I think this might be easier to read as just:

  tm->tm_mday = now->tm_mday;
  tm->tm_mon = now->tm_mon;
  tm->tm_year = now->tm_year;

But it's possible that the round-trip through mktime() and localtime_r()
in update_tm() has some value (I wonder what would happen at 2:30am on a
day when DST springs forward from 2am to 3am).

>  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);
>  }

OK, same here, except obviously we _do_ need to call update_tm() for its
adjustment.

> @@ -1204,6 +1206,7 @@ static const struct special {
>  	{ "AM", date_am },
>  	{ "never", date_never },
>  	{ "now", date_now },
> +	{ "today", date_now },
>  	{ NULL }
>  };

So before we did not understand "today" at all, but just ignored it.
Which worked because we try to make everything relative to "now" by
default anyway. Adding it as you do here makes sense, since now we are
using its ability to "override" the date set by things like "noon".

It is a little weird that "now" and "today" share the same
implementation. So notably, "noon now" does not override the time
(ignoring "noon" completely). But that is already the case before your
patch (and I think is just one of those approxidate "if it hurts, don't
do it" quirks).

> --- a/t/t0006-date.sh
> +++ b/t/t0006-date.sh
> @@ -178,10 +178,10 @@ check_approxidate '6am yesterday' '2009-08-29 06:00:00'
>  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 'noon yesterday' '2009-08-29 12:00:00'
>  (
>  	GIT_TEST_DATE_NOW=$(($GIT_TEST_DATE_NOW-12*60*60)); export GIT_TEST_DATE_NOW
> +	check_approxidate 'noon today' '2009-08-30 12:00:00'
> +	check_approxidate 'noon yesterday' '2009-08-29 12:00:00'
>  	check_approxidate 'January 5th noon pm' '2009-01-05 12:00:00'
>  )

Same comments on the tests as in patch 1. I think we'd want to add,
rather than replace, and put these in the same save/restore block rather
than using a subshell.

-Peff

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

* [PATCH v2 0/3] approxidate: tweak special date formats
  2025-03-18 18:01 [PATCH 0/2] approxidate: tweak special date formats Tuomas Ahola
  2025-03-18 18:02 ` [PATCH 1/2] approxidate: make "specials" respect fixed day-of-month Tuomas Ahola
  2025-03-18 18:02 ` [PATCH 2/2] approxidate: overwrite tm_mday for `now` and `yesterday` Tuomas Ahola
@ 2026-05-12 14:54 ` Tuomas Ahola
  2026-05-12 14:54   ` [PATCH v2 1/3] t0006: add support for approxidate test date adjustment Tuomas Ahola
                     ` (3 more replies)
  2 siblings, 4 replies; 23+ messages in thread
From: Tuomas Ahola @ 2026-05-12 14:54 UTC (permalink / raw)
  To: git; +Cc: Jeff King, Tuomas Ahola

The approxidate system is an endless source of absurdities.  Let's make the
usual "eh, that's crazy, let's do better with this input" type of fix[1], and
tweak some sharp edge cases, including one noticed by Linus back in 2006[2].

After this series, "tea" and "noon" will work predictably with all kinds of
date formats (today, yesterday, last Friday, January 5th, one year ago
yesterday...) regardless of the current time of day.

Links:
  1. https://lore.kernel.org/git/20181115144854.GB16450@sigill.intra.peff.net/
  2. https://lore.kernel.org/git/Pine.LNX.4.64.0610101102560.3952@g5.osdl.org/

Tuomas Ahola (3):
  t0006: add support for approxidate test date adjustment
  approxidate: make "specials" respect fixed day-of-month
  approxidate: use deferred mday adjustments for "specials"

 date.c          | 37 +++++++++++++++++++++++++++----------
 t/t0006-date.sh | 19 ++++++++++++++++++-
 2 files changed, 45 insertions(+), 11 deletions(-)

Intervall-diff mot v1:
1:  9bfff739fd < -:  ---------- approxidate: make "specials" respect fixed day-of-month
2:  1a4398e5a1 < -:  ---------- approxidate: overwrite tm_mday for `now` and `yesterday`
-:  ---------- > 1:  118f1825ac t0006: add support for approxidate test date adjustment
-:  ---------- > 2:  21c4858c47 approxidate: make "specials" respect fixed day-of-month
-:  ---------- > 3:  cf72403102 approxidate: use deferred mday adjustments for "specials"

base-commit: c44beea485f0f2feaf460e2ac87fdd5608d63cf0
-- 
2.30.2


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

* [PATCH v2 1/3] t0006: add support for approxidate test date adjustment
  2026-05-12 14:54 ` [PATCH v2 0/3] approxidate: tweak special date formats Tuomas Ahola
@ 2026-05-12 14:54   ` Tuomas Ahola
  2026-05-12 16:34     ` Junio C Hamano
  2026-05-12 18:35     ` Jeff King
  2026-05-12 14:54   ` [PATCH v2 2/3] approxidate: make "specials" respect fixed day-of-month Tuomas Ahola
                     ` (2 subsequent siblings)
  3 siblings, 2 replies; 23+ messages in thread
From: Tuomas Ahola @ 2026-05-12 14:54 UTC (permalink / raw)
  To: git; +Cc: Jeff King, Tuomas Ahola

t0006 uses a hard-coded test date and provides no convenient
way to override it temporarily.  Add an optional parameter to
check_approxidate to adjust the time as needed, and demonstrate
the feature with a new test.

Signed-off-by: Tuomas Ahola <taahol@utu.fi>
---
 t/t0006-date.sh | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/t/t0006-date.sh b/t/t0006-date.sh
index 53ced36df4..5d66267672 100755
--- a/t/t0006-date.sh
+++ b/t/t0006-date.sh
@@ -156,11 +156,18 @@ check_parse '2100-00-00 00:00:00 +11' bad
 REQUIRE_64BIT_TIME=
 
 check_approxidate() {
+	old_date=$GIT_TEST_DATE_NOW
+	GIT_TEST_DATE_NOW=$(($old_date${4:-+0}*60*60)); export GIT_TEST_DATE_NOW
+	caption=$1
+	if [ ! -z $4 ]; then
+		caption="$caption; offset $4h"
+	fi
 	echo "$1 -> $2 +0000" >expect
-	test_expect_${3:-success} "parse approxidate ($1)" "
+	test_expect_${3:-success} "parse approxidate ($caption)" "
 	test-tool date approxidate '$1' >actual &&
 	test_cmp expect actual
 	"
+	GIT_TEST_DATE_NOW=$old_date; export GIT_TEST_DATE_NOW
 }
 
 check_approxidate now '2009-08-30 19:20:00'
@@ -182,6 +189,8 @@ check_approxidate 'noon today' '2009-08-30 12:00:00'
 check_approxidate 'noon yesterday' '2009-08-29 12:00:00'
 check_approxidate 'January 5th noon pm' '2009-01-05 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' success +48
 
 check_approxidate 'last tuesday' '2009-08-25 19:20:00'
 check_approxidate 'July 5th' '2009-07-05 19:20:00'
-- 
2.30.2


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

* [PATCH v2 2/3] approxidate: make "specials" respect fixed day-of-month
  2026-05-12 14:54 ` [PATCH v2 0/3] approxidate: tweak special date formats Tuomas Ahola
  2026-05-12 14:54   ` [PATCH v2 1/3] t0006: add support for approxidate test date adjustment Tuomas Ahola
@ 2026-05-12 14:54   ` Tuomas Ahola
  2026-05-12 16:52     ` Junio C Hamano
  2026-05-12 14:54   ` [PATCH v2 3/3] approxidate: use deferred mday adjustments for "specials" Tuomas Ahola
  2026-05-14 11:55   ` [PATCH v3 0/4] approxidate: tweak special date formats Tuomas Ahola
  3 siblings, 1 reply; 23+ messages in thread
From: Tuomas Ahola @ 2026-05-12 14:54 UTC (permalink / raw)
  To: git; +Cc: Jeff King, Tuomas Ahola

The special approxidate time formats, "noon" and "tea", wrap
to the previous day if the current time is before 12 or 5 pm,
respectively.  That holds even when an actual date is supplied;
therefore, "10 May at tea" and "last Friday at noon" can cause
the date to be set to a seemingly wrong day:

	now -> 2026-05-12 11:00:00 +0000
	10 May at tea -> 2026-05-09 17:00:00 +0000
	last Friday at noon -> 2026-05-07 12:00:00 +0000
	One year ago yesterday at tea-time -> 2025-05-10 17:00:00 +0000

The last example is from Linus Torvalds who remarked in 2006
that the answer was "just silly and not even correct." [1]

As "last Friday at noon" is mentioned in the documentation
(date-formats.adoc) it would be nice if it worked correctly.
Let's fix the glitch with a simple patch.

Check whether we already have a specified (non-negative) mday
and make date_time() stick to it.  Add a suitable time offset
to the relevant test.

While we are at it, add "today" as an alias of "now", so that
"today at noon" will do the right thing, too, and assert that
with a new test.

Links:
  1. https://lore.kernel.org/git/Pine.LNX.4.64.0610101102560.3952@g5.osdl.org/

Signed-off-by: Tuomas Ahola <taahol@utu.fi>
---
 date.c          | 8 +++++++-
 t/t0006-date.sh | 4 ++++
 2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/date.c b/date.c
index 17a95077cf..e48cc2a4d7 100644
--- a/date.c
+++ b/date.c
@@ -1132,7 +1132,12 @@ static void date_yesterday(struct tm *tm, struct tm *now, int *num)
 
 static void date_time(struct tm *tm, struct tm *now, int hour)
 {
-	if (tm->tm_hour < hour)
+	/*
+	 * By default, "tea" and "noon" refer to last such time in the
+	 * past, be it today or yesterday.  With a specified mday,
+	 * that logic is overridden.
+	 */
+	if (tm->tm_mday < 0 && tm->tm_hour < hour)
 		update_tm(tm, now, 24*60*60);
 	tm->tm_hour = hour;
 	tm->tm_min = 0;
@@ -1204,6 +1209,7 @@ static const struct special {
 	{ "AM", date_am },
 	{ "never", date_never },
 	{ "now", date_now },
+	{ "today", date_now },
 	{ NULL }
 };
 
diff --git a/t/t0006-date.sh b/t/t0006-date.sh
index 5d66267672..e01d093514 100755
--- a/t/t0006-date.sh
+++ b/t/t0006-date.sh
@@ -186,8 +186,12 @@ 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' success -12
 check_approxidate 'noon yesterday' '2009-08-29 12:00:00'
+check_approxidate 'last Friday at noon' '2009-08-28 12:00:00'
+check_approxidate 'last Friday at noon' '2009-08-28 12:00:00' success -12
 check_approxidate 'January 5th noon pm' '2009-01-05 12:00:00'
+check_approxidate 'January 5th noon pm' '2009-01-05 12:00:00' success -12
 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' success +48
-- 
2.30.2


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

* [PATCH v2 3/3] approxidate: use deferred mday adjustments for "specials"
  2026-05-12 14:54 ` [PATCH v2 0/3] approxidate: tweak special date formats Tuomas Ahola
  2026-05-12 14:54   ` [PATCH v2 1/3] t0006: add support for approxidate test date adjustment Tuomas Ahola
  2026-05-12 14:54   ` [PATCH v2 2/3] approxidate: make "specials" respect fixed day-of-month Tuomas Ahola
@ 2026-05-12 14:54   ` Tuomas Ahola
  2026-05-14 11:55   ` [PATCH v3 0/4] approxidate: tweak special date formats Tuomas Ahola
  3 siblings, 0 replies; 23+ messages in thread
From: Tuomas Ahola @ 2026-05-12 14:54 UTC (permalink / raw)
  To: git; +Cc: Jeff King, Tuomas Ahola

There are cases where the "wrap-to-yesterday" behavior of "tea" and
"noon" should be reverted later on down the line, so that "today tea"
and "tea today" won't yield different results.  However, the logic of
approxidate doesn't seem to lend itself particularly well to
such cases.

Start tackling the issue by reusing negative values of `tm->tm_mday`
field for deferred date adjustments which can be easily reverted, so
that the default logic of the special formats only applies if we don't
get any explicit date (mday) specification.  In particular, overwrite
the field with -1 in "now" and "yesterday", so that those formats will
be relative to the current date.  That makes specifications like "tea
yesterday" behave more sensibly: instead of going backwards to the
last tea-time and then a day back, Git will now understand that as the
tea-time of yesterday.

Replace the call of `update_tm()` in `date_time()` with the assignment
`tm->tm_mday = -2`.  Add the corresponding code to handle that in
`update_tm()`, wrapping to the previous day if the field still holds
such assignment, meaning that we haven't seen any better specification
for the day-of-month.  On the other hand, `mday=-3` would mean going
two days back and so on.  Even though such functionality isn't
actually needed by this patch, it won't add much complexity in the
code and is rather natural way to handle such values.

As `date_time()` won't no longer need the `now` struct, mark the
associated function parameters as unused.  The parameters themselves
have to stay, however, as those functions are called through pointers
in `approxidate_alpha`.  Add relevant tests to cover the changes.

Signed-off-by: Tuomas Ahola <taahol@utu.fi>
---
 date.c          | 31 +++++++++++++++++++++----------
 t/t0006-date.sh |  4 ++++
 2 files changed, 25 insertions(+), 10 deletions(-)

diff --git a/date.c b/date.c
index e48cc2a4d7..795f1ac2e9 100644
--- a/date.c
+++ b/date.c
@@ -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) {
@@ -1121,45 +1130,47 @@ static void pending_number(struct tm *tm, int *num)
 static void date_now(struct tm *tm, struct tm *now, int *num)
 {
 	*num = 0;
+	tm->tm_mday = -1;
 	update_tm(tm, now, 0);
 }
 
 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)
 {
 	/*
 	 * By default, "tea" and "noon" refer to last such time in the
 	 * past, be it today or yesterday.  With a specified mday,
-	 * that logic is overridden.
+	 * or e.g. "noon today", that logic is overridden.
 	 */
 	if (tm->tm_mday < 0 && tm->tm_hour < hour)
-		update_tm(tm, now, 24*60*60);
+		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)
diff --git a/t/t0006-date.sh b/t/t0006-date.sh
index e01d093514..2670269bb7 100755
--- a/t/t0006-date.sh
+++ b/t/t0006-date.sh
@@ -187,9 +187,13 @@ 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' success -12
+check_approxidate 'noon today' '2009-09-01 12:00:00' success +36
 check_approxidate 'noon yesterday' '2009-08-29 12:00:00'
 check_approxidate 'last Friday at noon' '2009-08-28 12:00:00'
 check_approxidate 'last Friday at noon' '2009-08-28 12:00:00' success -12
+check_approxidate 'noon yesterday' '2009-08-29 12:00:00' success -12
+check_approxidate 'tea last saturday' '2009-08-29 17:00:00'
+check_approxidate 'tea last saturday' '2009-08-29 17:00:00' success -12
 check_approxidate 'January 5th noon pm' '2009-01-05 12:00:00'
 check_approxidate 'January 5th noon pm' '2009-01-05 12:00:00' success -12
 check_approxidate '10am noon' '2009-08-29 12:00:00'
-- 
2.30.2


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

* Re: [PATCH v2 1/3] t0006: add support for approxidate test date adjustment
  2026-05-12 14:54   ` [PATCH v2 1/3] t0006: add support for approxidate test date adjustment Tuomas Ahola
@ 2026-05-12 16:34     ` Junio C Hamano
  2026-05-12 18:35     ` Jeff King
  1 sibling, 0 replies; 23+ messages in thread
From: Junio C Hamano @ 2026-05-12 16:34 UTC (permalink / raw)
  To: Tuomas Ahola; +Cc: git, Jeff King

Tuomas Ahola <taahol@utu.fi> writes:

>  check_approxidate() {
> +	old_date=$GIT_TEST_DATE_NOW
> +	GIT_TEST_DATE_NOW=$(($old_date${4:-+0}*60*60)); export GIT_TEST_DATE_NOW
> +	caption=$1
> +	if [ ! -z $4 ]; then
> +		caption="$caption; offset $4h"
> +	fi

As you are not doing the test-date-now adjustment when $4 is not
given, wouldn't it be a lot easier to read if you did something like

	old_date=$GIT_TEST_DATE_NOW
	if test -n "$4"
	then
		# the convention for $4 is a bit weird in that it 
		# comes with its own +/- operator in front.
		GIT_TEST_DATE_NOW=$(( $old_date $4 * 60 * 60 ))
		caption="$1; offset $4h"
	else
        	caption=$1
	fi

instead?  Other two minor points are

 - Documentation/SubmittingPatches prefers an explicit "test" over
   "[ ... ]", and have "then", "else", etc. on their own lines.

 - As you never "unset" GIT_TEST_DATE_NOW, you do not have to keep
   exporting it.  It is not like there are two variables (one for
   shell, the other for environment) and every time you set the
   shell one you need to export to reflect the value to the
   environment one.  Rather, a single "export" marks a shell
   variable and every time it changes value, it is updated in the
   environment as well.

>  	echo "$1 -> $2 +0000" >expect
> -	test_expect_${3:-success} "parse approxidate ($1)" "
> +	test_expect_${3:-success} "parse approxidate ($caption)" "
>  	test-tool date approxidate '$1' >actual &&
>  	test_cmp expect actual
>  	"
> +	GIT_TEST_DATE_NOW=$old_date; export GIT_TEST_DATE_NOW
>  }
>  
>  check_approxidate now '2009-08-30 19:20:00'
> @@ -182,6 +189,8 @@ check_approxidate 'noon today' '2009-08-30 12:00:00'
>  check_approxidate 'noon yesterday' '2009-08-29 12:00:00'
>  check_approxidate 'January 5th noon pm' '2009-01-05 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' success +48
>  
>  check_approxidate 'last tuesday' '2009-08-25 19:20:00'
>  check_approxidate 'July 5th' '2009-07-05 19:20:00'

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

* Re: [PATCH v2 2/3] approxidate: make "specials" respect fixed day-of-month
  2026-05-12 14:54   ` [PATCH v2 2/3] approxidate: make "specials" respect fixed day-of-month Tuomas Ahola
@ 2026-05-12 16:52     ` Junio C Hamano
  0 siblings, 0 replies; 23+ messages in thread
From: Junio C Hamano @ 2026-05-12 16:52 UTC (permalink / raw)
  To: Tuomas Ahola; +Cc: git, Jeff King

Tuomas Ahola <taahol@utu.fi> writes:

> The special approxidate time formats, "noon" and "tea", wrap
> to the previous day if the current time is before 12 or 5 pm,
> respectively.  That holds even when an actual date is supplied;
> therefore, "10 May at tea" and "last Friday at noon" can cause
> the date to be set to a seemingly wrong day:
>
> 	now -> 2026-05-12 11:00:00 +0000
> 	10 May at tea -> 2026-05-09 17:00:00 +0000
> 	last Friday at noon -> 2026-05-07 12:00:00 +0000

It would help readers to say that Friday of that week was May 8th to
make it easier for them to see why this is a wrong answer.

> 	One year ago yesterday at tea-time -> 2025-05-10 17:00:00 +0000
>
> The last example is from Linus Torvalds who remarked in 2006
> that the answer was "just silly and not even correct." [1]

It may be just me, but it was hard for me to guess if you are
justifying how these answers are correct, or you are presenting
examples of wrong output.  Perhaps starting the paragraph with cases
where the "wrap to the previous" gets right to set the stage may
make it easier to understand?  Let's see...

    The ... 'noon' and 'tea', wrap to the ... before 12 or 5 pm,
    respectively.  So for example if it is 11am on 2026-05-12, then

	now  -> 2026-05-12 11:00:00 +0000
	noon -> 2026-05-11 11:00:00 +0000
	tea  -> 2026-05-11 17:00:00 +0000

    which would work well when you ask for "git log --since=tea",
    for example.

    That hold even when ... seemingly wrong day:

> As "last Friday at noon" is mentioned in the documentation
> (date-formats.adoc) it would be nice if it worked correctly.
> Let's fix the glitch with a simple patch.
>
> Check whether we already have a specified (non-negative) mday
> and make date_time() stick to it.  Add a suitable time offset
> to the relevant test.
>
> While we are at it, add "today" as an alias of "now", so that
> "today at noon" will do the right thing, too, and assert that
> with a new test.
>
> Links:
>   1. https://lore.kernel.org/git/Pine.LNX.4.64.0610101102560.3952@g5.osdl.org/
>
> Signed-off-by: Tuomas Ahola <taahol@utu.fi>
> ---
>  date.c          | 8 +++++++-
>  t/t0006-date.sh | 4 ++++
>  2 files changed, 11 insertions(+), 1 deletion(-)
>
> diff --git a/date.c b/date.c
> index 17a95077cf..e48cc2a4d7 100644
> --- a/date.c
> +++ b/date.c
> @@ -1132,7 +1132,12 @@ static void date_yesterday(struct tm *tm, struct tm *now, int *num)
>  
>  static void date_time(struct tm *tm, struct tm *now, int hour)
>  {
> -	if (tm->tm_hour < hour)
> +	/*
> +	 * By default, "tea" and "noon" refer to last such time in the
> +	 * past, be it today or yesterday.  With a specified mday,
> +	 * that logic is overridden.
> +	 */

Again, this may be just me, but I happen to find the version of
comment in Peff's review on the earlier iteration of this series
much easier to understand.

> +	if (tm->tm_mday < 0 && tm->tm_hour < hour)
>  		update_tm(tm, now, 24*60*60);
>  	tm->tm_hour = hour;
>  	tm->tm_min = 0;
> @@ -1204,6 +1209,7 @@ static const struct special {
>  	{ "AM", date_am },
>  	{ "never", date_never },
>  	{ "now", date_now },
> +	{ "today", date_now },

Hmph, this may not work very well for "git log --since=today", which
you may want to stop immediately when the traversal reaches a patch
written before the most recent midnight, instead of stopping without
giving anything back.

>  	{ NULL }
>  };
>  
> diff --git a/t/t0006-date.sh b/t/t0006-date.sh
> index 5d66267672..e01d093514 100755
> --- a/t/t0006-date.sh
> +++ b/t/t0006-date.sh
> @@ -186,8 +186,12 @@ 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' success -12
>  check_approxidate 'noon yesterday' '2009-08-29 12:00:00'
> +check_approxidate 'last Friday at noon' '2009-08-28 12:00:00'
> +check_approxidate 'last Friday at noon' '2009-08-28 12:00:00' success -12
>  check_approxidate 'January 5th noon pm' '2009-01-05 12:00:00'
> +check_approxidate 'January 5th noon pm' '2009-01-05 12:00:00' success -12
>  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' success +48

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

* Re: [PATCH v2 1/3] t0006: add support for approxidate test date adjustment
  2026-05-12 14:54   ` [PATCH v2 1/3] t0006: add support for approxidate test date adjustment Tuomas Ahola
  2026-05-12 16:34     ` Junio C Hamano
@ 2026-05-12 18:35     ` Jeff King
  1 sibling, 0 replies; 23+ messages in thread
From: Jeff King @ 2026-05-12 18:35 UTC (permalink / raw)
  To: Tuomas Ahola; +Cc: git

On Tue, May 12, 2026 at 05:54:28PM +0300, Tuomas Ahola wrote:

> t0006 uses a hard-coded test date and provides no convenient
> way to override it temporarily.  Add an optional parameter to
> check_approxidate to adjust the time as needed, and demonstrate
> the feature with a new test.

Makes sense, but two small-ish comments:

> +check_approxidate 'January 5th yesterday' '2008-12-31 19:20:00' success +48

One, it sucks to have to say "success" here, but is awkward because now
we have two optional arguments. There's nobody passing "failure" right
now, so we could just drop support, though that might be annoying later
when somebody wants to add a failing test. But we could perhaps switch
to allowing:

  check_approxidate --failure 'January 5th yesterday' ...etc

which is fairly natural.

This is something we've run into in many different test scripts, and I
think the harness could do a better job of supporting this. Perhaps with
something like:

  test_expect() {
	if "$GIT_TEST_EXPECT" = "fail"
	then
		test_expect_failure "$@"
	else
		test_expect_success "$@"
  }

  test_fails() {
	# probably needs to be more careful of one-shot with functions
	GIT_TEST_EXPECT=fail "$@"
  }

  # this is a normal passing test snippet
  test_expect 'foo' 'git foo'

  # this one expects failure, but it can be toggled easily by
  # removing the leading "test_fails" wrapper. Not much better
  # than swapping out s/failure/success/ now. But...
  test_fails test_expect 'bar' 'git bar'

  # this one just does the right thing if the helper function
  # is using test_expect under the hood
  test_fails check_approxidate ...

I dunno. It is probably too big a rabbit hole to do before your series,
so mostly I'm just thinking out loud.

> +check_approxidate 'January 5th yesterday' '2008-12-31 19:20:00' success +48

The second thing is that "+48" is pretty opaque. It's a relative offset
to some arbitrary point. To some degree the script already suffers from
that (all of the tests are using some arbitrary point), but I think the
offset (without units!) adds a layer of indirection that makes it even
more confusing.

I wonder how hard it would be to just take an arbitrary time instead,
and then you could write:

  check_approxidate 'January 5th yesterday' '2008-12-31 19:20:00' '2009-08-28 12:00:00'

or whatever. There is a chicken-and-egg problem with testing our date
routines and using the date routines to parse out the starting point.
But I think for approxidate, we could be using the strict parser (tested
separately earlier via check_parse) to handle the base time.

-Peff

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

* [PATCH v3 0/4] approxidate: tweak special date formats
  2026-05-12 14:54 ` [PATCH v2 0/3] approxidate: tweak special date formats Tuomas Ahola
                     ` (2 preceding siblings ...)
  2026-05-12 14:54   ` [PATCH v2 3/3] approxidate: use deferred mday adjustments for "specials" Tuomas Ahola
@ 2026-05-14 11:55   ` Tuomas Ahola
  2026-05-14 11:55     ` [PATCH v3 1/4] t0006: add support for approxidate test date adjustment Tuomas Ahola
                       ` (3 more replies)
  3 siblings, 4 replies; 23+ messages in thread
From: Tuomas Ahola @ 2026-05-14 11:55 UTC (permalink / raw)
  To: git; +Cc: Jeff King, Junio C Hamano, Tuomas Ahola

The approxidate system is an endless source of absurdities.  Let's make the
usual "eh, that's crazy, let's do better with this input" type of fix[1], and
tweak some sharp edge cases, including one noticed by Linus back in 2006[2].

After this series, "tea" and "noon" will work predictably with all kinds of
date formats (today, yesterday, last Friday, January 5th, one year ago
yesterday...) regardless of the current time of day.

Links:
  1. https://lore.kernel.org/git/20181115144854.GB16450@sigill.intra.peff.net/
  2. https://lore.kernel.org/git/Pine.LNX.4.64.0610101102560.3952@g5.osdl.org/

Tuomas Ahola (4):
  t0006: add support for approxidate test date adjustment
  approxidate: alias "today" to "now"
  approxidate: make "specials" respect fixed day-of-month
  approxidate: use deferred mday adjustments for "specials"

 date.c          | 36 ++++++++++++++++++++++++++----------
 t/t0006-date.sh | 41 ++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 66 insertions(+), 11 deletions(-)

Intervall-diff mot v2:
1:  118f1825ac < -:  ---------- t0006: add support for approxidate test date adjustment
2:  21c4858c47 < -:  ---------- approxidate: make "specials" respect fixed day-of-month
-:  ---------- > 1:  7ea9c9967b t0006: add support for approxidate test date adjustment
-:  ---------- > 2:  3a21727dbe approxidate: alias "today" to "now"
-:  ---------- > 3:  d1992d23d0 approxidate: make "specials" respect fixed day-of-month
3:  cf72403102 ! 4:  0b1a10305c approxidate: use deferred mday adjustments for "specials"
    @@ date.c: static void pending_number(struct tm *tm, int *num)
     +static void date_time(struct tm *tm, int hour)
      {
      	/*
    - 	 * By default, "tea" and "noon" refer to last such time in the
    - 	 * past, be it today or yesterday.  With a specified mday,
    --	 * that logic is overridden.
    -+	 * or e.g. "noon today", that logic is overridden.
    + 	 * 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)
     -		update_tm(tm, now, 24*60*60);
    @@ t/t0006-date.sh
     @@ t/t0006-date.sh: 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' success -12
    -+check_approxidate 'noon today' '2009-09-01 12:00:00' success +36
    + 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 'last Friday at noon' '2009-08-28 12:00:00'
    - check_approxidate 'last Friday at noon' '2009-08-28 12:00:00' success -12
    -+check_approxidate 'noon yesterday' '2009-08-29 12:00:00' success -12
    + check_approxidate 'last Friday at noon' '2009-08-28 12:00:00' '-12 hours'
    ++check_approxidate 'noon yesterday' '2009-08-29 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' success -12
    ++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' success -12
    + check_approxidate 'January 5th noon pm' '2009-01-05 12:00:00' '-12 hours'
      check_approxidate '10am noon' '2009-08-29 12:00:00'

base-commit: c44beea485f0f2feaf460e2ac87fdd5608d63cf0
-- 
2.30.2


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

* [PATCH v3 1/4] t0006: add support for approxidate test date adjustment
  2026-05-14 11:55   ` [PATCH v3 0/4] approxidate: tweak special date formats Tuomas Ahola
@ 2026-05-14 11:55     ` Tuomas Ahola
  2026-05-14 11:55     ` [PATCH v3 2/4] approxidate: alias "today" to "now" Tuomas Ahola
                       ` (2 subsequent siblings)
  3 siblings, 0 replies; 23+ messages in thread
From: Tuomas Ahola @ 2026-05-14 11:55 UTC (permalink / raw)
  To: git; +Cc: Jeff King, Junio C Hamano, Tuomas Ahola

t0006 uses a hard-coded test date and provides no convenient
way to override it temporarily.  Add an optional parameter to
check_approxidate to adjust the time as needed, and demonstrate
the feature with a new test.

Signed-off-by: Tuomas Ahola <taahol@utu.fi>
---

Notes:
    > As you are not doing the test-date-now adjustment when $4 is not
    > given, wouldn't it be a lot easier to read if you did something like
    >
    > 	old_date=$GIT_TEST_DATE_NOW
    > 	if test -n "$4"
    > 	then
    > 		# the convention for $4 is a bit weird in that it
    > 		# comes with its own +/- operator in front.
    > 		GIT_TEST_DATE_NOW=$(( $old_date $4 * 60 * 60 ))
    > 		caption="$1; offset $4h"
    > 	else
    >         	caption=$1
    > 	fi
    >
    > instead?  Other two minor points are
    >
    >  - Documentation/SubmittingPatches prefers an explicit "test" over
    >    "[ ... ]", and have "then", "else", etc. on their own lines.
    >
    >  - As you never "unset" GIT_TEST_DATE_NOW, you do not have to keep
    >    exporting it.  It is not like there are two variables (one for
    >    shell, the other for environment) and every time you set the
    >    shell one you need to export to reflect the value to the
    >    environment one.  Rather, a single "export" marks a shell
    >    variable and every time it changes value, it is updated in the
    >    environment as well.
    >
    
    Thanks, applied.
    
    > One, it sucks to have to say "success" here, but is awkward because now
    > we have two optional arguments. There's nobody passing "failure" right
    > now, so we could just drop support, though that might be annoying later
    > when somebody wants to add a failing test. But we could perhaps switch
    > to allowing:
    >
    
    Ok, now it works without "success" in between, and "failure" works without
    an offset, too.
    
    	check_approxidate <test-string> <expected-result> [<test-time-offset>] [failure]
    
    > The second thing is that "+48" is pretty opaque. It's a relative offset
    > to some arbitrary point. To some degree the script already suffers from
    > that (all of the tests are using some arbitrary point), but I think the
    > offset (without units!) adds a layer of indirection that makes it even
    > more confusing.
    >
    
    Good catch.  Now it is at least marginally better with the added units.

 t/t0006-date.sh | 33 ++++++++++++++++++++++++++++++++-
 1 file changed, 32 insertions(+), 1 deletion(-)

diff --git a/t/t0006-date.sh b/t/t0006-date.sh
index 53ced36df4..c7667bade2 100755
--- a/t/t0006-date.sh
+++ b/t/t0006-date.sh
@@ -155,12 +155,41 @@ 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'
@@ -182,6 +211,8 @@ check_approxidate 'noon today' '2009-08-30 12:00:00'
 check_approxidate 'noon yesterday' '2009-08-29 12:00:00'
 check_approxidate 'January 5th noon pm' '2009-01-05 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'
-- 
2.30.2


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

* [PATCH v3 2/4] approxidate: alias "today" to "now"
  2026-05-14 11:55   ` [PATCH v3 0/4] approxidate: tweak special date formats Tuomas Ahola
  2026-05-14 11:55     ` [PATCH v3 1/4] t0006: add support for approxidate test date adjustment Tuomas Ahola
@ 2026-05-14 11:55     ` Tuomas Ahola
  2026-05-14 15:36       ` Junio C Hamano
  2026-05-14 11:55     ` [PATCH v3 3/4] approxidate: make "specials" respect fixed day-of-month Tuomas Ahola
  2026-05-14 11:55     ` [PATCH v3 4/4] approxidate: use deferred mday adjustments for "specials" Tuomas Ahola
  3 siblings, 1 reply; 23+ messages in thread
From: Tuomas Ahola @ 2026-05-14 11:55 UTC (permalink / raw)
  To: git; +Cc: Jeff King, Junio C Hamano, Tuomas Ahola

As far as approxidate in concerned, "today" is a no-op.  That makes
it functionally equivalent to "now" in commands like

        $ git log --since=today

Make that behavior explicit by binding "today" to `date_now()`.
That way later patches can give "today" some functionality in
cases like "today at noon".

Signed-off-by: Tuomas Ahola <taahol@utu.fi>
---

Notes:
    > Hmph, this may not work very well for "git log --since=today", which
    > you may want to stop immediately when the traversal reaches a patch
    > written before the most recent midnight, instead of stopping without
    > giving anything back.
    >
    
    Sorry, I don't know if I understood.  Does the patch change the behavior of
    that command somehow?  Is there some kind of edge case I missed?
    
    That said, if we do want to change it so that "git log --since=today"
    worked like "--since=midnight", this seems to do the trick:
    
    ```
    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_midnight(tm, now, num);
    	date_now(tm, now, num);
    }
    ```

 date.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/date.c b/date.c
index 17a95077cf..412aca6dc4 100644
--- a/date.c
+++ b/date.c
@@ -1204,6 +1204,7 @@ static const struct special {
 	{ "AM", date_am },
 	{ "never", date_never },
 	{ "now", date_now },
+	{ "today", date_now },
 	{ NULL }
 };
 
-- 
2.30.2


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

* [PATCH v3 3/4] approxidate: make "specials" respect fixed day-of-month
  2026-05-14 11:55   ` [PATCH v3 0/4] approxidate: tweak special date formats Tuomas Ahola
  2026-05-14 11:55     ` [PATCH v3 1/4] t0006: add support for approxidate test date adjustment Tuomas Ahola
  2026-05-14 11:55     ` [PATCH v3 2/4] approxidate: alias "today" to "now" Tuomas Ahola
@ 2026-05-14 11:55     ` Tuomas Ahola
  2026-05-14 16:06       ` Junio C Hamano
  2026-05-14 11:55     ` [PATCH v3 4/4] approxidate: use deferred mday adjustments for "specials" Tuomas Ahola
  3 siblings, 1 reply; 23+ messages in thread
From: Tuomas Ahola @ 2026-05-14 11:55 UTC (permalink / raw)
  To: git; +Cc: Jeff King, Junio C Hamano, Tuomas Ahola

The special approxidate time formats, "noon" and "tea" differ from
"12pm" and "5pm" by having the feature of wrapping to the previous day
if the current time is before those hours:

	now  -> 2026-05-13 11:00:00 +0000

	12pm -> 2026-05-13 12:00:00 +0000
	5pm  -> 2026-05-13 17:00:00 +0000

	noon -> 2026-05-12 12:00:00 +0000
	tea  -> 2026-05-12 17:00:00 +0000

However, that logic carries too far.  Even when the date is specified,
the behavior of the "specials" depends on the current time.  Assuming
the same time as above, we get:

	today at noon -> 2026-05-12 12:00:00 +0000 (should be 13 May)
	13 May at tea -> 2026-05-12 17:00:00 +0000

or, using an example mentioned in date-formats.adoc:

	last Friday at noon -> 2026-05-07 12:00:00 +0000 (should be 8 May)

The quirk seems to be rather old.  Already in 2006, Linus Torvalds
remarked that the date yielded by "one year ago yesterday at tea-time"
was "just silly and not even correct".  Indeed, even today it gives:

	One year ago yesterday at tea-time -> 2025-05-11 17:00:00 +0000
	  (should be 12 May)

Let's fix all of those with a simple patch.  Check whether we already
have a specified day-of-month in `tm->tm_mday` and make `date_time()`
stick to it.  Ensure the correct behavior with relevant tests.

Links:
  1. https://lore.kernel.org/git/Pine.LNX.4.64.0610101102560.3952@g5.osdl.org/

Signed-off-by: Tuomas Ahola <taahol@utu.fi>
---

Notes:
    > Again, this may be just me, but I happen to find the version of
    > comment in Peff's review on the earlier iteration of this series
    > much easier to understand.
    >
    
    Thanks, applied.

 date.c          | 6 +++++-
 t/t0006-date.sh | 4 ++++
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/date.c b/date.c
index 412aca6dc4..73879d202c 100644
--- a/date.c
+++ b/date.c
@@ -1132,7 +1132,11 @@ static void date_yesterday(struct tm *tm, struct tm *now, int *num)
 
 static void date_time(struct tm *tm, struct tm *now, int hour)
 {
-	if (tm->tm_hour < hour)
+	/*
+	 * 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)
 		update_tm(tm, now, 24*60*60);
 	tm->tm_hour = hour;
 	tm->tm_min = 0;
diff --git a/t/t0006-date.sh b/t/t0006-date.sh
index c7667bade2..d800cb30fe 100755
--- a/t/t0006-date.sh
+++ b/t/t0006-date.sh
@@ -208,8 +208,12 @@ 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 yesterday' '2009-08-29 12:00:00'
+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 '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 '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'
-- 
2.30.2


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

* [PATCH v3 4/4] approxidate: use deferred mday adjustments for "specials"
  2026-05-14 11:55   ` [PATCH v3 0/4] approxidate: tweak special date formats Tuomas Ahola
                       ` (2 preceding siblings ...)
  2026-05-14 11:55     ` [PATCH v3 3/4] approxidate: make "specials" respect fixed day-of-month Tuomas Ahola
@ 2026-05-14 11:55     ` Tuomas Ahola
  3 siblings, 0 replies; 23+ messages in thread
From: Tuomas Ahola @ 2026-05-14 11:55 UTC (permalink / raw)
  To: git; +Cc: Jeff King, Junio C Hamano, Tuomas Ahola

There are cases where the "wrap-to-yesterday" behavior of "tea" and
"noon" should be reverted later on down the line, so that "today tea"
and "tea today" won't yield different results.  However, the logic of
approxidate doesn't seem to lend itself particularly well to
such cases.

Start tackling the issue by reusing negative values of `tm->tm_mday`
field for deferred date adjustments which can be easily reverted, so
that the default logic of the special formats only applies if we don't
get any explicit date (mday) specification.  In particular, overwrite
the field with -1 in "now" and "yesterday", so that those formats will
be relative to the current date.  That makes specifications like "tea
yesterday" behave more sensibly: instead of going backwards to the
last tea-time and then a day back, Git will now understand that as the
tea-time of yesterday.

Replace the call of `update_tm()` in `date_time()` with the assignment
`tm->tm_mday = -2`.  Add the corresponding code to handle that in
`update_tm()`, wrapping to the previous day if the field still holds
such assignment, meaning that we haven't seen any better specification
for the day-of-month.  On the other hand, `mday=-3` would mean going
two days back and so on.  Even though such functionality isn't
actually needed by this patch, it won't add much complexity in the
code and is rather natural way to handle such values.

As `date_time()` won't no longer need the `now` struct, mark the
associated function parameters as unused.  The parameters themselves
have to stay, however, as those functions are called through pointers
in `approxidate_alpha`.  Add relevant tests to cover the changes.

Signed-off-by: Tuomas Ahola <taahol@utu.fi>
---
 date.c          | 29 ++++++++++++++++++++---------
 t/t0006-date.sh |  4 ++++
 2 files changed, 24 insertions(+), 9 deletions(-)

diff --git a/date.c b/date.c
index 73879d202c..914c733737 100644
--- a/date.c
+++ b/date.c
@@ -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) {
@@ -1121,44 +1130,46 @@ static void pending_number(struct tm *tm, int *num)
 static void date_now(struct tm *tm, struct tm *now, int *num)
 {
 	*num = 0;
+	tm->tm_mday = -1;
 	update_tm(tm, now, 0);
 }
 
 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 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)
-		update_tm(tm, now, 24*60*60);
+		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)
diff --git a/t/t0006-date.sh b/t/t0006-date.sh
index d800cb30fe..432b92f841 100755
--- a/t/t0006-date.sh
+++ b/t/t0006-date.sh
@@ -209,9 +209,13 @@ 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 '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 'noon yesterday' '2009-08-29 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 '10am noon' '2009-08-29 12:00:00'
-- 
2.30.2


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

* Re: [PATCH v3 2/4] approxidate: alias "today" to "now"
  2026-05-14 11:55     ` [PATCH v3 2/4] approxidate: alias "today" to "now" Tuomas Ahola
@ 2026-05-14 15:36       ` Junio C Hamano
  2026-05-14 21:07         ` Tuomas Ahola
  0 siblings, 1 reply; 23+ messages in thread
From: Junio C Hamano @ 2026-05-14 15:36 UTC (permalink / raw)
  To: Tuomas Ahola; +Cc: git, Jeff King

Tuomas Ahola <taahol@utu.fi> writes:

>     Sorry, I don't know if I understood.  Does the patch change the behavior of
>     that command somehow?  Is there some kind of edge case I missed?

No, I did not think it was a good idea to carve the behaviour in
stone that "git log --since=today" behaves as if it were given "git
log --since=now".  My reaction would have been very different if we
were deliberatly and explicitly saying "today is synonym for now",
but the thing is, it is not a designed behaviour but what
approxidate does for anything it does not understand, e.g.

    git log --since=decay
    git log --since=bogus

all behave as if it were given --since=now.

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

* Re: [PATCH v3 3/4] approxidate: make "specials" respect fixed day-of-month
  2026-05-14 11:55     ` [PATCH v3 3/4] approxidate: make "specials" respect fixed day-of-month Tuomas Ahola
@ 2026-05-14 16:06       ` Junio C Hamano
  0 siblings, 0 replies; 23+ messages in thread
From: Junio C Hamano @ 2026-05-14 16:06 UTC (permalink / raw)
  To: Tuomas Ahola; +Cc: git, Jeff King

Tuomas Ahola <taahol@utu.fi> writes:

> The special approxidate time formats, "noon" and "tea" differ from
> "12pm" and "5pm" by having the feature of wrapping to the previous day
> if the current time is before those hours:
>
> 	now  -> 2026-05-13 11:00:00 +0000
>
> 	12pm -> 2026-05-13 12:00:00 +0000
> 	5pm  -> 2026-05-13 17:00:00 +0000
>
> 	noon -> 2026-05-12 12:00:00 +0000
> 	tea  -> 2026-05-12 17:00:00 +0000
>
> However, that logic carries too far.  Even when the date is specified,
> the behavior of the "specials" depends on the current time.  Assuming
> the same time as above, we get:
>
> 	today at noon -> 2026-05-12 12:00:00 +0000 (should be 13 May)
> 	13 May at tea -> 2026-05-12 17:00:00 +0000
>
> or, using an example mentioned in date-formats.adoc:
>
> 	last Friday at noon -> 2026-05-07 12:00:00 +0000 (should be 8 May)
>
> The quirk seems to be rather old.  Already in 2006, Linus Torvalds
> remarked that the date yielded by "one year ago yesterday at tea-time"
> was "just silly and not even correct".  Indeed, even today it gives:
>
> 	One year ago yesterday at tea-time -> 2025-05-11 17:00:00 +0000
> 	  (should be 12 May)
>
> Let's fix all of those with a simple patch.  Check whether we already
> have a specified day-of-month in `tm->tm_mday` and make `date_time()`
> stick to it.  Ensure the correct behavior with relevant tests.


I find this vastly easier to follow the reasoning, compared to the
previous iteration.  Very nicely done.



>
> Links:
>   1. https://lore.kernel.org/git/Pine.LNX.4.64.0610101102560.3952@g5.osdl.org/
>
> Signed-off-by: Tuomas Ahola <taahol@utu.fi>
> ---
>
> Notes:
>     > Again, this may be just me, but I happen to find the version of
>     > comment in Peff's review on the earlier iteration of this series
>     > much easier to understand.
>     >
>     
>     Thanks, applied.
>
>  date.c          | 6 +++++-
>  t/t0006-date.sh | 4 ++++
>  2 files changed, 9 insertions(+), 1 deletion(-)
>
> diff --git a/date.c b/date.c
> index 412aca6dc4..73879d202c 100644
> --- a/date.c
> +++ b/date.c
> @@ -1132,7 +1132,11 @@ static void date_yesterday(struct tm *tm, struct tm *now, int *num)
>  
>  static void date_time(struct tm *tm, struct tm *now, int hour)
>  {
> -	if (tm->tm_hour < hour)
> +	/*
> +	 * 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)
>  		update_tm(tm, now, 24*60*60);
>  	tm->tm_hour = hour;
>  	tm->tm_min = 0;
> diff --git a/t/t0006-date.sh b/t/t0006-date.sh
> index c7667bade2..d800cb30fe 100755
> --- a/t/t0006-date.sh
> +++ b/t/t0006-date.sh
> @@ -208,8 +208,12 @@ 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 yesterday' '2009-08-29 12:00:00'
> +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 '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 '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'

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

* Re: [PATCH v3 2/4] approxidate: alias "today" to "now"
  2026-05-14 15:36       ` Junio C Hamano
@ 2026-05-14 21:07         ` Tuomas Ahola
  2026-05-15  1:27           ` Junio C Hamano
  0 siblings, 1 reply; 23+ messages in thread
From: Tuomas Ahola @ 2026-05-14 21:07 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Jeff King

Junio C Hamano <gitster@pobox.com> wrote:

> Tuomas Ahola <taahol@utu.fi> writes:
> 
> >     Sorry, I don't know if I understood.  Does the patch change the behavior of
> >     that command somehow?  Is there some kind of edge case I missed?
> 
> No, I did not think it was a good idea to carve the behaviour in
> stone that "git log --since=today" behaves as if it were given "git
> log --since=now".  My reaction would have been very different if we
> were deliberatly and explicitly saying "today is synonym for now",
> but the thing is, it is not a designed behaviour but what
> approxidate does for anything it does not understand, e.g.
> 
>     git log --since=decay
>     git log --since=bogus
> 
> all behave as if it were given --since=now.

Thanks for spelling that out.  So, as there is no deliberative
decision behind the current behaviour of "today", the code has
to remain non-committed on that; we are not at liberty to codify
the status quo.  Right?  But perhaps we can find a least common
denominator.  "Today" means the current day (well, obviously),
and this seems to be enough to get "today at noon" and such to work:

```
static void date_today(struct tm *tm, struct tm *now, int *num)
{
	*num = 0;
	tm->tm_mday = now->tm_mday;
}
```

It gets the job done whitout setting in stone too much anything
that is up for debate.  Do you see that could work?

--Tuomas

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

* Re: [PATCH v3 2/4] approxidate: alias "today" to "now"
  2026-05-14 21:07         ` Tuomas Ahola
@ 2026-05-15  1:27           ` Junio C Hamano
  2026-05-15  1:38             ` Junio C Hamano
  0 siblings, 1 reply; 23+ messages in thread
From: Junio C Hamano @ 2026-05-15  1:27 UTC (permalink / raw)
  To: Tuomas Ahola; +Cc: git, Jeff King

Tuomas Ahola <taahol@utu.fi> writes:

> Junio C Hamano <gitster@pobox.com> wrote:
>
>> Tuomas Ahola <taahol@utu.fi> writes:
>> 
>> >     Sorry, I don't know if I understood.  Does the patch change the behavior of
>> >     that command somehow?  Is there some kind of edge case I missed?
>> 
>> No, I did not think it was a good idea to carve the behaviour in
>> stone that "git log --since=today" behaves as if it were given "git
>> log --since=now".  My reaction would have been very different if we
>> were deliberatly and explicitly saying "today is synonym for now",
>> but the thing is, it is not a designed behaviour but what
>> approxidate does for anything it does not understand, e.g.
>> 
>>     git log --since=decay
>>     git log --since=bogus
>> 
>> all behave as if it were given --since=now.
>
> Thanks for spelling that out.  So, as there is no deliberative
> decision behind the current behaviour of "today", the code has
> to remain non-committed on that; we are not at liberty to codify
> the status quo.  Right?

Not right.  It is more like "Even though we try not to change
existing behavoiur left and right without a good reason to avoid
breaking existing users' expectations, we should be able to "fix"
what is not intended behaviour but is something the code happened to
be doing, especially if the current behaviour does not make sense.

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

* Re: [PATCH v3 2/4] approxidate: alias "today" to "now"
  2026-05-15  1:27           ` Junio C Hamano
@ 2026-05-15  1:38             ` Junio C Hamano
  2026-05-15  5:02               ` Tuomas Ahola
  0 siblings, 1 reply; 23+ messages in thread
From: Junio C Hamano @ 2026-05-15  1:38 UTC (permalink / raw)
  To: Tuomas Ahola; +Cc: git, Jeff King

Junio C Hamano <gitster@pobox.com> writes:

> Tuomas Ahola <taahol@utu.fi> writes:
>
>> Junio C Hamano <gitster@pobox.com> wrote:
>>
>>> Tuomas Ahola <taahol@utu.fi> writes:
>>> 
>>> >     Sorry, I don't know if I understood.  Does the patch change the behavior of
>>> >     that command somehow?  Is there some kind of edge case I missed?
>>> 
>>> No, I did not think it was a good idea to carve the behaviour in
>>> stone that "git log --since=today" behaves as if it were given "git
>>> log --since=now".  My reaction would have been very different if we
>>> were deliberatly and explicitly saying "today is synonym for now",
>>> but the thing is, it is not a designed behaviour but what
>>> approxidate does for anything it does not understand, e.g.
>>> 
>>>     git log --since=decay
>>>     git log --since=bogus
>>> 
>>> all behave as if it were given --since=now.
>>
>> Thanks for spelling that out.  So, as there is no deliberative
>> decision behind the current behaviour of "today", the code has
>> to remain non-committed on that; we are not at liberty to codify
>> the status quo.  Right?
>
> Not right.  It is more like "Even though we try not to change
> existing behavoiur left and right without a good reason to avoid
> breaking existing users' expectations, we should be able to "fix"
> what is not intended behaviour but is something the code happened to
> be doing, especially if the current behaviour does not make sense.

And the other half of the discussion is that once we explicitly say
"today means right now" and make it official, it makes it much harder
to fix it later.  So we need to be very careful in our first attempt.

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

* Re: [PATCH v3 2/4] approxidate: alias "today" to "now"
  2026-05-15  1:38             ` Junio C Hamano
@ 2026-05-15  5:02               ` Tuomas Ahola
  0 siblings, 0 replies; 23+ messages in thread
From: Tuomas Ahola @ 2026-05-15  5:02 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Jeff King

Junio C Hamano <gitster@pobox.com> wrote:

> Junio C Hamano <gitster@pobox.com> writes:
> 
> > Tuomas Ahola <taahol@utu.fi> writes:
> >
> >> Junio C Hamano <gitster@pobox.com> wrote:
> >>
> >>> Tuomas Ahola <taahol@utu.fi> writes:
> >>> 
> >>> >     Sorry, I don't know if I understood.  Does the patch change the behavior of
> >>> >     that command somehow?  Is there some kind of edge case I missed?
> >>> 
> >>> No, I did not think it was a good idea to carve the behaviour in
> >>> stone that "git log --since=today" behaves as if it were given "git
> >>> log --since=now".  My reaction would have been very different if we
> >>> were deliberatly and explicitly saying "today is synonym for now",
> >>> but the thing is, it is not a designed behaviour but what
> >>> approxidate does for anything it does not understand, e.g.
> >>> 
> >>>     git log --since=decay
> >>>     git log --since=bogus
> >>> 
> >>> all behave as if it were given --since=now.
> >>
> >> Thanks for spelling that out.  So, as there is no deliberative
> >> decision behind the current behaviour of "today", the code has
> >> to remain non-committed on that; we are not at liberty to codify
> >> the status quo.  Right?
> >
> > Not right.  It is more like "Even though we try not to change
> > existing behavoiur left and right without a good reason to avoid
> > breaking existing users' expectations, we should be able to "fix"
> > what is not intended behaviour but is something the code happened to
> > be doing, especially if the current behaviour does not make sense.

Well, that's not far off from what I wrote.  I just meant we cannot
make the current (somewhat accidental) behaviour official *just because*
it happens to be the status quo.

> 
> And the other half of the discussion is that once we explicitly say "today
> means right now" and make it official, it makes it much harder to fix it
> later.  So we need to be very careful in our first attempt.

Roger that.

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

end of thread, other threads:[~2026-05-15  5:02 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-03-18 18:01 [PATCH 0/2] approxidate: tweak special date formats Tuomas Ahola
2025-03-18 18:02 ` [PATCH 1/2] approxidate: make "specials" respect fixed day-of-month Tuomas Ahola
2025-04-04  8:19   ` Jeff King
2025-03-18 18:02 ` [PATCH 2/2] approxidate: overwrite tm_mday for `now` and `yesterday` Tuomas Ahola
2025-04-04  8:40   ` Jeff King
2026-05-12 14:54 ` [PATCH v2 0/3] approxidate: tweak special date formats Tuomas Ahola
2026-05-12 14:54   ` [PATCH v2 1/3] t0006: add support for approxidate test date adjustment Tuomas Ahola
2026-05-12 16:34     ` Junio C Hamano
2026-05-12 18:35     ` Jeff King
2026-05-12 14:54   ` [PATCH v2 2/3] approxidate: make "specials" respect fixed day-of-month Tuomas Ahola
2026-05-12 16:52     ` Junio C Hamano
2026-05-12 14:54   ` [PATCH v2 3/3] approxidate: use deferred mday adjustments for "specials" Tuomas Ahola
2026-05-14 11:55   ` [PATCH v3 0/4] approxidate: tweak special date formats Tuomas Ahola
2026-05-14 11:55     ` [PATCH v3 1/4] t0006: add support for approxidate test date adjustment Tuomas Ahola
2026-05-14 11:55     ` [PATCH v3 2/4] approxidate: alias "today" to "now" Tuomas Ahola
2026-05-14 15:36       ` Junio C Hamano
2026-05-14 21:07         ` Tuomas Ahola
2026-05-15  1:27           ` Junio C Hamano
2026-05-15  1:38             ` Junio C Hamano
2026-05-15  5:02               ` Tuomas Ahola
2026-05-14 11:55     ` [PATCH v3 3/4] approxidate: make "specials" respect fixed day-of-month Tuomas Ahola
2026-05-14 16:06       ` Junio C Hamano
2026-05-14 11:55     ` [PATCH v3 4/4] approxidate: use deferred mday adjustments for "specials" Tuomas Ahola

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.