GNU date falls back to UTC0 when the timezone is invalid. I guess that
isn't too intuitive, see a twitter user who ran into this gotcha (and an
unhinged reply...) [1].
Perhaps it would be good for 'date --debug' to warning about this on
typical platforms using /usr/share/zoneinfo? Here is the output using an
example parse-datetime patch:
$ TZ=invalid ./src/date --debug -d '2026'
date: parsed number part: 20:26:00
date: input timezone: TZ="invalid" environment value
date: using specified time as starting value: '20:26:00'
date: using current date as starting value: '(Y-M-D) 2026-08-09'
date: starting date/time: '(Y-M-D) 2026-08-09 20:26:00'
date: '(Y-M-D) 2026-08-09 20:26:00' = 1786307160 epoch-seconds
date: timezone: TZ="invalid" environment value
date: warning: TZ="invalid" is not a valid timezone. Falling back to
Universal Time
date: final: 1786307160.000000000 (epoch-seconds)
date: final: (Y-M-D) 2026-08-09 20:26:00 (UTC)
date: final: (Y-M-D) 2026-08-09 20:26:00 (UTC+00)
date: output format: ‘%a %b %e %r %Z %Y’
Sun Aug 9 08:26:00 PM invalid 2026
The message should probably be made shorter, but it is just a draft.
Here is the patch:
diff --git a/lib/parse-datetime.y b/lib/parse-datetime.y
index 22894f3091..e7bd70d4bb 100644
--- a/lib/parse-datetime.y
+++ b/lib/parse-datetime.y
@@ -57,6 +57,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <sys/stat.h>
#include "gettext.h"
@@ -2361,7 +2362,30 @@ parse_datetime_body (struct timespec *result, char const
*p,
else if (streq (tzstring, "UTC0"))
dbg_fputs (_("timezone: Universal Time\n"));
else
- dbg_printf (_("timezone: TZ=\"%s\" environment value\n"), tzstring);
+ {
+ dbg_printf (_("timezone: TZ=\"%s\" environment value\n"), tzstring);
+ struct stat st;
+ char const zoneinfo[] = "/usr/share/zoneinfo/";
+ if (0 <= stat (zoneinfo, &st))
+ {
+ idx_t const tzstring_len = strlen (tzstring);
+ char *name = malloc (sizeof zoneinfo + tzstring_len);
+ if (name)
+ {
+ memcpy (name, zoneinfo, sizeof zoneinfo - 1);
+ memcpy (name + sizeof zoneinfo - 1, tzstring,
+ tzstring_len + 1);
+ if (stat (name, &st) < 0)
+ {
+ dbg_printf (_("warning: TZ=\"%s\" is not a valid "
+ "timezone. "
+ "Falling back to Universal Time\n"),
+ tzstring);
+ }
+ free (name);
+ }
+ }
+ }
intmax_t sec = result->tv_sec;
int nsec = result->tv_nsec;
Collin
[1] https://x.com/trentdotsol/status/2085037902614917230