From: Jeff King <peff@peff.net>
To: Tuomas Ahola <taahol@utu.fi>
Cc: git@vger.kernel.org
Subject: Re: [PATCH 1/2] approxidate: make "specials" respect fixed day-of-month
Date: Fri, 4 Apr 2025 04:19:11 -0400 [thread overview]
Message-ID: <20250404081911.GA762635@coredump.intra.peff.net> (raw)
In-Reply-To: <20250318180201.3653-2-taahol@utu.fi>
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
next prev parent reply other threads:[~2025-04-04 8:19 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
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 [this message]
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
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250404081911.GA762635@coredump.intra.peff.net \
--to=peff@peff.net \
--cc=git@vger.kernel.org \
--cc=taahol@utu.fi \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).