{"thread":{"id":"65644","subject":"[RFC PATCH] approxidate: make \"today\" wrap to midnight","startedAt":"2026-05-15T20:58:21Z","lastAt":"2026-05-16T13:54:11Z","messageCount":5,"participants":["Tuomas Ahola","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"543425","messageId":"20260515205803.26211-1-taahol@utu.fi","threadId":"65644","inReplyTo":null,"subject":"[RFC PATCH] approxidate: make \"today\" wrap to midnight","fromName":"Tuomas Ahola","fromEmail":"taahol@utu.fi","sentAt":"2026-05-15T20:58:03Z","receivedAt":"2026-05-15T20:58:21Z","isPatch":true,"body":"Although some commands do reject invalid approxidate expressions,\nin other cases those are simply evaluated as the current time.\nOftentimes that is a perfectly good compromise to handle silly\nrequests, but it isn't without rough edges.\n\nLet's consider what \"git log --since=today\" should yield.\nAs it happens that \"today\" isn't actually a valid approxidate\nformat, the command currently tries to list commits with\n*future* timestamps.  Perhaps it would make more sense if\nit returned the commits made since midnight---that is,\nduring the current day.\n\nMoreover, a revision parameter \"@{today}\" is currently outright\nrejected.  Making \"today\" a valid approxidate time format could\nmake a natural way to specify the state of the ref at the start\nof the current day.\n\nBind \"today\" to new function `date_today()` as an approxidate\nspecial.  Make it return the last midnight if no specific time\nis given; i.e. retain the old behavior of \"noon today\" and such.\n\nSigned-off-by: Tuomas Ahola <taahol@utu.fi>\n---\n\nNotes:\n    The \"Jan 5 today\" test is adapted from\n    \n      c27cc94fad (approxidate: handle pending number for \"specials\", 2018-11-02):\n    \n    > (saying \"Jan 5 yesterday\" should not respect the number at all).\n\n date.c          | 10 ++++++++++\n t/t0006-date.sh |  2 ++\n 2 files changed, 12 insertions(+)\n\ndiff --git a/date.c b/date.c\nindex 17a95077cf..343d6aab6f 100644\n--- a/date.c\n+++ b/date.c\n@@ -1192,6 +1192,15 @@ static void date_never(struct tm *tm, struct tm *now UNUSED, int *num)\n \t*num = 0;\n }\n \n+static void date_today(struct tm *tm, struct tm *now, int *num UNUSED)\n+{\n+\tif (tm->tm_hour == now->tm_hour &&\n+\t    tm->tm_min == now->tm_min &&\n+\t    tm->tm_sec == now->tm_sec)\n+\t\tdate_time(tm, now, 0);\n+\tupdate_tm(tm, now, 0);\n+}\n+\n static const struct special {\n \tconst char *name;\n \tvoid (*fn)(struct tm *, struct tm *, int *);\n@@ -1204,6 +1213,7 @@ static const struct special {\n \t{ \"AM\", date_am },\n \t{ \"never\", date_never },\n \t{ \"now\", date_now },\n+\t{ \"today\", date_today },\n \t{ NULL }\n };\n \ndiff --git a/t/t0006-date.sh b/t/t0006-date.sh\nindex 53ced36df4..07bf6115ab 100755\n--- a/t/t0006-date.sh\n+++ b/t/t0006-date.sh\n@@ -164,6 +164,7 @@ check_approxidate() {\n }\n \n check_approxidate now '2009-08-30 19:20:00'\n+check_approxidate today '2009-08-30 00:00:00'\n check_approxidate '5 seconds ago' '2009-08-30 19:19:55'\n check_approxidate 5.seconds.ago '2009-08-30 19:19:55'\n check_approxidate 10.minutes.ago '2009-08-30 19:10:00'\n@@ -187,6 +188,7 @@ check_approxidate 'last tuesday' '2009-08-25 19:20:00'\n check_approxidate 'July 5th' '2009-07-05 19:20:00'\n check_approxidate '06/05/2009' '2009-06-05 19:20:00'\n check_approxidate '06.05.2009' '2009-05-06 19:20:00'\n+check_approxidate 'Jan 5 today' '2009-01-30 00:00:00'\n \n check_approxidate 'Jun 6, 5AM' '2009-06-06 05:00:00'\n check_approxidate '5AM Jun 6' '2009-06-06 05:00:00'\n\nbase-commit: 94f057755b7941b321fd11fec1b2e3ca5313a4e0\n-- \n2.30.2\n\n"},{"id":"543430","messageId":"87lddkcjau.fsf@gitster.g","threadId":"65644","inReplyTo":"20260515205803.26211-1-taahol@utu.fi","subject":"Re: [RFC PATCH] approxidate: make \"today\" wrap to midnight","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-05-16T00:03:21Z","receivedAt":"2026-05-16T00:03:27Z","isPatch":true,"body":"Tuomas Ahola <taahol@utu.fi> writes:\n\n> Although some commands do reject invalid approxidate expressions,\n> in other cases those are simply evaluated as the current time.\n> Oftentimes that is a perfectly good compromise to handle silly\n> requests, but it isn't without rough edges.\n>\n> Let's consider what \"git log --since=today\" should yield.\n> As it happens that \"today\" isn't actually a valid approxidate\n> format, the command currently tries to list commits with\n> *future* timestamps.  Perhaps it would make more sense if\n> it returned the commits made since midnight---that is,\n> during the current day.\n\nI actually am of two minds about this.  \n\nWhat should \"git log --until=today\" do when you run it in the late\nafternoon?  Wouldn't you want to see what you did in the morning and\nearly afternoon?\n\nBecause we cannot define \"today\" as \"--since=today means the latest\nmidnight and later, while --until=today means until the end of today\n[*]\" without introducing an extra hint to calls to approxidate() to\ntell it who is calling for what, it is impossible to give these two\nsensible behavior at the same time.\n\n    Side note: but because the existing history is all about the past,\n    \"until the end of today\" is by definition a synonym for \"up to\n    now\", so defining \"today\" the same as \"now\" would make \"until\"\n    behave just as sensibly as if we define it as \"the end of today\".\n\nIn practice, using \"--until\" to *not* truncate at all (which is what\n--until=now or --until=end.of.today would essentially mean) has no\npractical value, while \"--since=beginning.of.today\" does have more\nutility, allowing you to specify \"the last 8 hours and 50 minutes\"\nwithout knowing that it is now at 08:50 in the morning.  So I am\nstill in favor of interpreting \"today\" as \"the latest midnight, the\nbeginning of today\" because that would give us a more useful\nbehavior than other possible definitions.  We may want to strengthen\nthe justification behind the chosen definition of why we chose what\nwe chose over any other time in today with something like what I\nsaid above, mentioning \"--until\".\n\nThanks.\n"},{"id":"543447","messageId":"20260516113622.23902-1-taahol@utu.fi","threadId":"65644","inReplyTo":"20260515205803.26211-1-taahol@utu.fi","subject":"[PATCH v2] approxidate: make \"today\" wrap to midnight","fromName":"Tuomas Ahola","fromEmail":"taahol@utu.fi","sentAt":"2026-05-16T11:36:22Z","receivedAt":"2026-05-16T11:37:25Z","isPatch":true,"body":"Although some commands do reject invalid approxidate expressions,\nin other cases those are simply evaluated as the current time.\nOftentimes that is a perfectly good compromise to handle silly\nrequests, but it isn't without rough edges.\n\nBecause of the silent acceptance, it is easy to forget that\n\"today\" isn't actually a valid approxidate format.  That is\na bit awkward because while the fallback logic of using the\ncurrent time does make some sense, there is no deliberative\ndecision behind such behavior of \"today\".  Indeed, whatever\n(non-)action \"today\" currently has, is just an accidental\nside effect.\n\nThat means \"git log --since=today\" is currently unlikely to\nprint anything at all as it tries to list commits dated with\n*future* timestamps.  Arguably it would be more useful to\nlist the commits of the current day---i.e. those made since\nmidnight.\n\nOn the other hand, \"git log --until=today\" doesn't really\nfilter commits at all.  Changing the definition of \"today\"\nwould make it return the commits made before the current day.\nThat isn't without problems though---running \"git log\n--until=today\" in the late afternoon could reasonably include\nthe work done earlier that day (as the command currently\ndoes do).\n\nStill the utility of no-op \"--until=today\" is debatable and\nperhaps outweighed by the pros of having \"--since=today\" to\nmean \"--since=midnight\".  The thing is that the approxidate\nmachinery doesn't know about its consumers, so the meaning\nof \"today\" has to be the same for \"--since\" and \"--until\".\n\nIn fact, \"git log --until=\" is documented as\n\n\t`--until=<date>`::\n\t`--before=<date>`::\n\t\tShow commits older than _<date>_,\n\nso excluding commits made today would actually match the\ndocumentation more closely.\n\nMoreover, a revision parameter \"@{today}\" is currently outright\nrejected.  Making \"today\" a valid approxidate time format could\nmake a natural way to specify the state of the ref at the start\nof the current day.\n\nBind \"today\" to new function `date_today()` as an approxidate\nspecial.  Make it return the last midnight if no specific time\nis given; i.e. retain the old behavior of \"noon today\" and such.\n\nDocument the new behavior of \"git log --since=today\" in\nrev-list-options.adoc.\n\nSigned-off-by: Tuomas Ahola <taahol@utu.fi>\n---\nIntervall-diff mot v1:\n1:  849f058baf ! 1:  86bcb70ac2 approxidate: make \"today\" wrap to midnight\n    @@ Commit message\n         Oftentimes that is a perfectly good compromise to handle silly\n         requests, but it isn't without rough edges.\n     \n    -    Let's consider what \"git log --since=today\" should yield.\n    -    As it happens that \"today\" isn't actually a valid approxidate\n    -    format, the command currently tries to list commits with\n    -    *future* timestamps.  Perhaps it would make more sense if\n    -    it returned the commits made since midnight---that is,\n    -    during the current day.\n    +    Because of the silent acceptance, it is easy to forget that\n    +    \"today\" isn't actually a valid approxidate format.  That is\n    +    a bit awkward because while the fallback logic of using the\n    +    current time does make some sense, there is no deliberative\n    +    decision behind such behavior of \"today\".  Indeed, whatever\n    +    (non-)action \"today\" currently has, is just an accidental\n    +    side effect.\n    +\n    +    That means \"git log --since=today\" is currently unlikely to\n    +    print anything at all as it tries to list commits dated with\n    +    *future* timestamps.  Arguably it would be more useful to\n    +    list the commits of the current day---i.e. those made since\n    +    midnight.\n    +\n    +    On the other hand, \"git log --until=today\" doesn't really\n    +    filter commits at all.  Changing the definition of \"today\"\n    +    would make it return the commits made before the current day.\n    +    That isn't without problems though---running \"git log\n    +    --until=today\" in the late afternoon could reasonably include\n    +    the work done earlier that day (as the command currently\n    +    does do).\n    +\n    +    Still the utility of no-op \"--until=today\" is debatable and\n    +    perhaps outweighed by the pros of having \"--since=today\" to\n    +    mean \"--since=midnight\".  The thing is that the approxidate\n    +    machinery doesn't know about its consumers, so the meaning\n    +    of \"today\" has to be the same for \"--since\" and \"--until\".\n    +\n    +    In fact, \"git log --until=\" is documented as\n    +\n    +            `--until=<date>`::\n    +            `--before=<date>`::\n    +                    Show commits older than _<date>_,\n    +\n    +    so excluding commits made today would actually match the\n    +    documentation more closely.\n     \n         Moreover, a revision parameter \"@{today}\" is currently outright\n         rejected.  Making \"today\" a valid approxidate time format could\n    @@ Commit message\n         special.  Make it return the last midnight if no specific time\n         is given; i.e. retain the old behavior of \"noon today\" and such.\n     \n    +    Document the new behavior of \"git log --since=today\" in\n    +    rev-list-options.adoc.\n    +\n         Signed-off-by: Tuomas Ahola <taahol@utu.fi>\n     \n    + ## Documentation/rev-list-options.adoc ##\n    +@@ Documentation/rev-list-options.adoc: ordering and formatting options, such as `--reverse`.\n    + \n    + `--since=<date>`::\n    + `--after=<date>`::\n    +-\tShow commits more recent than _<date>_.\n    ++\tShow commits more recent than _<date>_.  As a special case,\n    ++\t'today' means the last midnight.\n    + \n    + `--since-as-filter=<date>`::\n    + \tShow all commits more recent than _<date>_. This visits\n    +\n      ## date.c ##\n     @@ date.c: static void date_never(struct tm *tm, struct tm *now UNUSED, int *num)\n      \t*num = 0;\n\n Documentation/rev-list-options.adoc |  3 ++-\n date.c                              | 10 ++++++++++\n t/t0006-date.sh                     |  2 ++\n 3 files changed, 14 insertions(+), 1 deletion(-)\n\ndiff --git a/Documentation/rev-list-options.adoc b/Documentation/rev-list-options.adoc\nindex 2d195a1474..a5abadf689 100644\n--- a/Documentation/rev-list-options.adoc\n+++ b/Documentation/rev-list-options.adoc\n@@ -23,7 +23,8 @@ ordering and formatting options, such as `--reverse`.\n \n `--since=<date>`::\n `--after=<date>`::\n-\tShow commits more recent than _<date>_.\n+\tShow commits more recent than _<date>_.  As a special case,\n+\t'today' means the last midnight.\n \n `--since-as-filter=<date>`::\n \tShow all commits more recent than _<date>_. This visits\ndiff --git a/date.c b/date.c\nindex 17a95077cf..343d6aab6f 100644\n--- a/date.c\n+++ b/date.c\n@@ -1192,6 +1192,15 @@ static void date_never(struct tm *tm, struct tm *now UNUSED, int *num)\n \t*num = 0;\n }\n \n+static void date_today(struct tm *tm, struct tm *now, int *num UNUSED)\n+{\n+\tif (tm->tm_hour == now->tm_hour &&\n+\t    tm->tm_min == now->tm_min &&\n+\t    tm->tm_sec == now->tm_sec)\n+\t\tdate_time(tm, now, 0);\n+\tupdate_tm(tm, now, 0);\n+}\n+\n static const struct special {\n \tconst char *name;\n \tvoid (*fn)(struct tm *, struct tm *, int *);\n@@ -1204,6 +1213,7 @@ static const struct special {\n \t{ \"AM\", date_am },\n \t{ \"never\", date_never },\n \t{ \"now\", date_now },\n+\t{ \"today\", date_today },\n \t{ NULL }\n };\n \ndiff --git a/t/t0006-date.sh b/t/t0006-date.sh\nindex 53ced36df4..07bf6115ab 100755\n--- a/t/t0006-date.sh\n+++ b/t/t0006-date.sh\n@@ -164,6 +164,7 @@ check_approxidate() {\n }\n \n check_approxidate now '2009-08-30 19:20:00'\n+check_approxidate today '2009-08-30 00:00:00'\n check_approxidate '5 seconds ago' '2009-08-30 19:19:55'\n check_approxidate 5.seconds.ago '2009-08-30 19:19:55'\n check_approxidate 10.minutes.ago '2009-08-30 19:10:00'\n@@ -187,6 +188,7 @@ check_approxidate 'last tuesday' '2009-08-25 19:20:00'\n check_approxidate 'July 5th' '2009-07-05 19:20:00'\n check_approxidate '06/05/2009' '2009-06-05 19:20:00'\n check_approxidate '06.05.2009' '2009-05-06 19:20:00'\n+check_approxidate 'Jan 5 today' '2009-01-30 00:00:00'\n \n check_approxidate 'Jun 6, 5AM' '2009-06-06 05:00:00'\n check_approxidate '5AM Jun 6' '2009-06-06 05:00:00'\n\nbase-commit: 94f057755b7941b321fd11fec1b2e3ca5313a4e0\n-- \n2.30.2\n\n"},{"id":"543451","messageId":"xmqqik8ncw98.fsf@gitster.g","threadId":"65644","inReplyTo":"20260516113622.23902-1-taahol@utu.fi","subject":"Re: [PATCH v2] approxidate: make \"today\" wrap to midnight","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-05-16T13:35:47Z","receivedAt":"2026-05-16T13:35:50Z","isPatch":true,"body":"Tuomas Ahola <taahol@utu.fi> writes:\n\n> Although some commands do reject invalid approxidate expressions,\n> in other cases those are simply evaluated as the current time.\n> Oftentimes that is a perfectly good compromise to handle silly\n> requests, but it isn't without rough edges.\n> ...\n> Bind \"today\" to new function `date_today()` as an approxidate\n> special.  Make it return the last midnight if no specific time\n> is given; i.e. retain the old behavior of \"noon today\" and such.\n>\n> Document the new behavior of \"git log --since=today\" in\n> rev-list-options.adoc.\n>\n> Signed-off-by: Tuomas Ahola <taahol@utu.fi>\n> ---\n\nI like this construction of argument.\n\nHow does this patch mesh with your earlier effort to make \"noon\" and\n\"tea\" more sensible?  Should we eject the \"today is now\" step from\nthat series and instead queue this patch in its place?\n\nThanks.\n"},{"id":"543454","messageId":"20260516135400.2UqFV%taahol@utu.fi","threadId":"65644","inReplyTo":"xmqqik8ncw98.fsf@gitster.g","subject":"Re: [PATCH v2] approxidate: make \"today\" wrap to midnight","fromName":"Tuomas Ahola","fromEmail":"taahol@utu.fi","sentAt":"2026-05-16T13:54:00Z","receivedAt":"2026-05-16T13:54:11Z","isPatch":true,"body":"Junio C Hamano <gitster@pobox.com> wrote:\n\n> Tuomas Ahola <taahol@utu.fi> writes:\n> \n> > Although some commands do reject invalid approxidate expressions,\n> > in other cases those are simply evaluated as the current time.\n> > Oftentimes that is a perfectly good compromise to handle silly\n> > requests, but it isn't without rough edges.\n> > ...\n> > Bind \"today\" to new function `date_today()` as an approxidate\n> > special.  Make it return the last midnight if no specific time\n> > is given; i.e. retain the old behavior of \"noon today\" and such.\n> >\n> > Document the new behavior of \"git log --since=today\" in\n> > rev-list-options.adoc.\n> >\n> > Signed-off-by: Tuomas Ahola <taahol@utu.fi>\n> > ---\n> \n> I like this construction of argument.\n> \n> How does this patch mesh with your earlier effort to make \"noon\" and\n> \"tea\" more sensible?  Should we eject the \"today is now\" step from\n> that series and instead queue this patch in its place?\n> \n> Thanks.\n\nYes.  I have already rebased the series on top of this patch.  I will\nsoon(ish) post v4 without \"today is now\" step.\n\n--Tuomas\n"}]}