Skip to content

Several TZ related fixes#75

Merged
rockorager merged 6 commits into
rockorager:mainfrom
AloisMahdal:tz_fixes
Jun 20, 2026
Merged

Several TZ related fixes#75
rockorager merged 6 commits into
rockorager:mainfrom
AloisMahdal:tz_fixes

Conversation

@AloisMahdal

@AloisMahdal AloisMahdal commented Jun 14, 2026

Copy link
Copy Markdown
Contributor

Details are in commit messages; feel free to cherry-pick and/or request changes (or squash as needed).

  • 2 minor fixes in README
  • using juicy main in README example
  • fixing crash when TZ="0", ie. numeric (should return error)
  • fixing crash when TZ="", ie. returning UTC instead (like glibc)

The last one is the most interesting: the empty string case is not clearly specified, so @rockorager , should zeit follow what glibc does? If not, I'd be happy to change it to some other behavior.

AloisMahdal and others added 6 commits June 14, 2026 19:55
POSIX[1] does not describe the empty string case: it's either starting
with colon (implementation-defined) or at least 3 bytes for 'std'
designation.

I decided to follow example of glibc.  From tzset(3):

> If the TZ variable does appear in the environment, but its value
> is empty, or its value cannot be interpreted using any of the formats
> specified below, then Coordinated Universal Time (UTC) is used.

A side note: this is actually a bit broken in glibc: the empty case is
checked but sets the designation to "Universal", which is not a valid
designation but results in what behaves as UTC.  (Except that word
"Universal", not "UTC" appears in as designation--just like with any
"random" text that is not valid sub-path of zoneinfo.)

  [1]: https://pubs.opengroup.org/onlinepubs/9699919799.2016edition/basedefs/V1_chap08.html
The `i -= 1;` line would crash if TZ started with a numeric character,
which is not valid POSIX TZ, so it should return error.InvalidPosix.

I've also added check that the designation must be at least 3
characters, as per POSIX[1]:

> std and dst
>    Indicate no less than three, nor more than {TZNAME_MAX}, bytes that are
>    the designation for the standard (std) or the alternative (dst -such as
>    Daylight Savings Time) timezone. Only std is required; if dst is missing,
>    then the alternative time does not apply in this locale.

I haven't added the TZNAME_MAX check as it would require larger changes
and would probably aply to the quoted case as well.

  [1]: https://pubs.opengroup.org/onlinepubs/9699919799.2016edition/basedefs/V1_chap08.html
The POSIX TZ parser accepted malformed input and could split fields incorrectly when offsets or names were missing. In particular, DST offsets at end of string updated the standard offset, and malformed strings such as UTC,foo or short DST names were accepted.

Parse standard and daylight names consistently, require valid time fields, fix DST offset assignment, and add regressions for malformed TZ strings and empty TZ handling.
@rockorager rockorager merged commit ed64c36 into rockorager:main Jun 20, 2026
@rockorager

Copy link
Copy Markdown
Owner

Thanks!

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

Successfully merging this pull request may close these issues.

2 participants