threads / discuss / 61891

Date and time processing issue

Subject: Date and time processing issue

## tl;dr

4 messages between Aug 2, 2024 and Aug 5, 2024.

replies: 3people: 3as markdown or json

the.tester@mac.com· Aug 2, 2024, 09:46 UTC · lore
Hi all,
Context: 
I’m preparing an example repo to be used as an example and for exercises for a tutorial I’m preparing set in time travel story, which should explain why I’m doing what I’m doing).
For this I am using the environement variable 'GIT_COMMITTER_DATE' and the '—date’ option to set these time stamps.
Observartion: 
When attempting to commit changes in some cases the following error is reported:
> GIT_COMMITTER_DATE="31 Dec 23:59:60 1969 +0100" git commit -m "Begs sharable holistic policy" --date "10 Apr 02:42:06 1970 +0100"
fatal: invalid date format: 31 Dec 23:59:60 1969 +0100
A second later, thigs work as I expect:
 > GIT_COMMITTER_DATE="01 Jan 00:00:00 1970 +0100" git commit -m "Begs sharable holistic policy" --date "10 Apr 02:42:06 1970 +0100"
[main 4fc6ea0] Begs sharable holistic policy
How to reproduce:
$ mkdir tmp
$ cd tmp
$ git init
Initialized empty Git repository in …/tmp/.git/
$ echo "Some content" > non-empty-file.txt
$ git add .
$ GIT_COMMITTER_DATE="31 Dec 23:59:60 1969 +0100" git commit -m "Demo commit" --date "12 Dec 23:59:60 1969 +0100"
fatal: invalid date format: 31 Dec 23:59:60 1969 +0100
$ GIT_COMMITTER_DATE="01 Jan 00:00:00 1970 +0100" git commit -m "Demo commit" --date "01 Jan 00:00:00 1970 +0100"
[main (root-commit) a5c7d72] Demo commit
 Date: Thu Jan 1 00:00:00 1970 +0000
 1 file changed, 1 insertion(+)
 create mode 100644 non-empty-file.txt
The same lines from a short shell script:

$ cat reproduction_sctipt.sh mkdir tmp cd tmp git init echo "Some content" > non-empty-file.txt git add . GIT_COMMITTER_DATE="31 Dec 23:59:60 1969 +0100" git commit -m "Demo commit" --date "12 Dec 23:59:60 1969 +0100" GIT_COMMITTER_DATE="01 Jan 00:00:00 1970 +0100" git commit -m "Demo commit" --date "01 Jan 00:00:00 1970 +0100"

System & version info:
Git version: 2.45.2
OS: macOS Sonoma 14.6 x86_64
Shell: zsh 5.9
(My) Interpretation:

To me, the error message is at least misleading. It also seem to be hidin the underlying issue that git (commit) doesn’t accept time stamps before the epoch.

Given that 1970-01-01 00:00:00 seems to be the lower boundary, I expected some time in 2038-01-19 to be the corresponding upper boundary. However the same error message is given when the date is >= 2100-01-01 00:00:00.

Personally, I think that at least the error message is misleading. (I’d say it’s a bug, if one that’s not particularly likely to run into). I expect the error message to point to the real problem, which is not a wrong date format, but the value the timestamp represents.

I’d also expect that correctly formatted time stamps containing valid date & time information should be processed correctly. (at least for dates after Friday 15 October 1582 (as the day before was Thursday 4 October 1582)

Am I doing it wrong? Is it a bug? Am I expecting too much? Can I do anything to make a wider date range available?

Best regards
Stephan
Junio C Hamano· Aug 2, 2024, 16:19 UTC · re: the.tester@mac.com · lore

Re: Date and time processing issue

the.tester@mac.com writes:
> To me, the error message is at least misleading. 

Correct. The error message is prepared for the most common case where people ask for an invalid format, but does not pay attention to the fact that some timestamps are not out of range in the Git timescale and such an out of range timestamp can be fed to the program.

Something along the following line may be a good first step to fix it.

 builtin/commit.c | 2 +-
 ident.c          | 3 ++-
 2 files changed, 3 insertions(+), 2 deletions(-)
diff --git c/builtin/commit.c w/builtin/commit.c
index 66427ba82d..24de55ae86 100644
--- c/builtin/commit.c
+++ w/builtin/commit.c
@@ -657,7 +657,7 @@ static void determine_author_info(struct strbuf *author_ident)
 	if (force_date) {
 		struct strbuf date_buf = STRBUF_INIT;
 		if (parse_force_date(force_date, &date_buf))
-			die(_("invalid date format: %s"), force_date);
+			die(_("invalid format or date out of range: %s"), force_date);
 		set_ident_var(&date, strbuf_detach(&date_buf, NULL));
 	}
 
diff --git c/ident.c w/ident.c
index caf41fb2a9..d18773554d 100644
--- c/ident.c
+++ w/ident.c
@@ -528,7 +528,8 @@ const char *fmt_ident(const char *name, const char *email,
 		strbuf_addch(ident, ' ');
 		if (date_str && date_str[0]) {
 			if (parse_date(date_str, ident) < 0)
-				die(_("invalid date format: %s"), date_str);
+				die(_("invalid format or date out of range: %s"),
+				    date_str);
 		}
 		else
 			strbuf_addstr(ident, ident_default_date());
the.tester@mac.com· Aug 4, 2024, 14:15 UTC · re: Junio C Hamano · lore

Re: Date and time processing issue

Show 30 quoted lines
> On 2. Aug 2024, at 18:19, Junio C Hamano <gitster@pobox.com> wrote:
> 
> the.tester@mac.com writes:
> 
>> To me, the error message is at least misleading.
> 
> Correct.  The error message is prepared for the most common case
> where people ask for an invalid format, but does not pay attention
> to the fact that some timestamps are not out of range in the Git
> timescale and such an out of range timestamp can be fed to the
> program.
> 
> Something along the following line may be a good first step to fix
> it.
> 
> builtin/commit.c | 2 +-
> ident.c          | 3 ++-
> 2 files changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git c/builtin/commit.c w/builtin/commit.c
> index 66427ba82d..24de55ae86 100644
> --- c/builtin/commit.c
> +++ w/builtin/commit.c
> ………
> or date out of range: %s"),
> +    date_str);
> }
> else
> strbuf_addstr(ident, ident_default_date());
> 

Yes, that would improve the error message. Would it make sense to create a pull request for this? – If so, should I do it? Or you?, Neither or us?

(That said, I wished I were familiar enough with C, to allow Git processing of a wider range of dates, but I’m not.)
Jeff King· Aug 5, 2024, 01:14 UTC · re: the.tester@mac.com · lore

Re: Date and time processing issue

On Fri, Aug 02, 2024 at 11:46:30AM +0200, the.tester@mac.com wrote:
Show 7 quoted lines
> To me, the error message is at least misleading. 
> It also seem to be hidin the underlying issue that git (commit)
> doesn’t accept time stamps before the epoch.
> 
> Given that 1970-01-01 00:00:00 seems to be the lower boundary, I
> expected some time in 2038-01-19 to be the corresponding upper
> boundary.

We use an unsigned value (hence the lower bound being at the epoch), so in a 32-bit world the high boundary would be 2106. But we actually use uintmax_t these days, so it's effectively infinite (even no 32-bit systems, there should be _some_ larger type available). But...

> However the same error message is given when the date is >= 2100-01-01
> 00:00:00.

...the sloppy tm_to_time_t() code does not handle conversions past 2100 due to the leap year skip there. There's more discussion in:

  https://lore.kernel.org/git/20240604093345.GA1279521@coredump.intra.peff.net/

That message mentions patches to handle negative timestamps completely. You can see them here:

  https://github.com/peff/git/jk/time-negative-wip

It works fine on Linux, but IIRC I got stuck on the system time-handling functions of Windows being unhappy. Probably solvable by implementing more custom code.

If you're interested in trying to push it over the finish line, I'd be happy to discuss it.

Although...
> I’d also expect that correctly formatted time stamps containing valid
> date & time information should be processed correctly.  (at least for
> dates after Friday 15 October 1582 (as the day before was Thursday 4
> October 1582)

I'm not sure how my implementation would handle this. The tm_to_time_t() fallback doesn't know anything about historical calendar shifts, and going in the reverse direction would depend on your system gmtime(). So probably:

 - if you feed a correct epoch timestamp for October 4th (e.g., "git
   commit --date=@-") you may or may not get the right result. Certainly
   on Windows if we have to use fallback code you wouldn't. But even GNU
   date doesn't seem to handle this:
     $ date --date=@-12219361438
     Thu Oct 14 00:00:00 LMT 1582
 - we'd always use custom code for going the other way. So:
     git commit --date=1582-10-04
   would give you an epoch 11 days before the 15th, not 1 day.

Even still, IMHO handling negative timestamps at all would be a huge improvement over the status quo. And we should be correct down to the second for "recent" stuff (like say, code written in the 1960's).

-Peff

← back to recent threads