Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

date(1) does not include timezone in some cases #9

Closed
wezm opened this issue Jul 15, 2023 · 0 comments
Closed

date(1) does not include timezone in some cases #9

wezm opened this issue Jul 15, 2023 · 0 comments

Comments

@wezm
Copy link

wezm commented Jul 15, 2023

The date(1) man page says that the timezone should be included when passing -Iseconds or -R but I'm always getting no timezone:

# Chimera
$ date -Iseconds
2023-07-15T09:34:37

$ ls -ld /etc/localtime
lrwxrwxrwx  1 root  root  38 Jun 15 10:45 /etc/localtime -> /usr/share/zoneinfo/Australia/Brisbane

I confirmed it works as documented on a FreeBSD 13.2 system:

#FreeBSD
$ date -Iseconds
2023-07-15T09:32:49+10:00

For -I this is how date attempts to get the time zone:

if (iso8601_selected > iso8601_fmts) {
(void)strftime_bsd(tzbuf, sizeof(tzbuf), "%z", lt);
memmove(&tzbuf[4], &tzbuf[3], 3);
tzbuf[3] = ':';
strlcat(buf, tzbuf, sizeof(buf));
}

When strftime_bsd processes %z it does a number of checks:

The first is:

if (t->tm_isdst < 0)

In my testing localtime() is returning a struct tm with tm_isdst set to 0, so it should get past this condition and into this:

#ifdef TM_GMTOFF
diff = t->TM_GMTOFF;
#else /* !defined TM_GMTOFF */
/*
* C99 says that the UTC offset must
* be computed by looking only at
* tm_isdst. This requirement is
* incorrect, since it means the code
* must rely on magic (in this case
* altzone and timezone), and the
* magic might not have the correct
* offset. Doing things correctly is
* tricky and requires disobeying C99;
* see GNU C strftime for details.
* For now, punt and conform to the
* standard, even though it's incorrect.
*
* C99 says that %z must be replaced by the
* empty string if the time zone is not
* determinable, so output nothing if the
* appropriate variables are not available.
*/
if (t->tm_isdst == 0)
#ifdef USG_COMPAT
diff = -timezone;
#else /* !defined USG_COMPAT */
continue;
#endif /* !defined USG_COMPAT */
else
#ifdef ALTZONE
diff = -altzone;
#else /* !defined ALTZONE */
continue;
#endif /* !defined ALTZONE */
#endif /* !defined TM_GMTOFF */

It's unclear to me which of the compile time definitions are set. It seems than in FreeBSD these are set in tzconfig.h. It seems that that code was not imported in 65d666e, which might mean that all of them are unset, which looks like it would fall though all the tests and skip over %z resulting in the observed behaviour.

@wezm wezm changed the title date(1) does not include timezone date(1) does not include timezone in some cases Jul 15, 2023
@q66 q66 closed this as completed in 83b19a0 Jul 16, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant