Skip to content

ICU-13694 Support TZ set to a zoneinfo file path in timezone detection#4063

Open
vlasky wants to merge 1 commit into
unicode-org:mainfrom
vlasky:ICU-13694-tz-zoneinfo-path
Open

ICU-13694 Support TZ set to a zoneinfo file path in timezone detection#4063
vlasky wants to merge 1 commit into
unicode-org:mainfrom
vlasky:ICU-13694-tz-zoneinfo-path

Conversation

@vlasky

@vlasky vlasky commented Jul 6, 2026

Copy link
Copy Markdown

Supersedes #2213 by @jungshik, rebased onto the current realpath-based TZDEFAULT logic in putil.cpp and restructured per the review feedback on that PR.

Problem

On Linux with glibc (and on other platforms with tzset()), the TZ environment variable may be set to the full path of a zoneinfo file, with or without a leading colon, e.g. TZ=:/usr/share/zoneinfo/America/New_York. Some Linux distributions configure TZ this way. In that case ICU's host timezone detection previously returned the whole path as the timezone ID, so detection failed: TimeZone::detectHostTimeZone() reported the raw path (e.g. /usr/share/zoneinfo/Asia/Seoul) as the zone ID.

Fix

In uprv_tzname(), when TZ holds an absolute path, extract the Olson ID from the portion of the path following /zoneinfo/ (TZZONEINFOTAIL), mirroring the existing handling of the /etc/localtime symlink target. Notes:

  • A path is recognized before the isValidOlsonID() check, because the directories above the Olson ID need not look like an Olson ID themselves: they may contain digits, e.g. a tzdata version such as /nix/store/abc-tzdata-2024a/share/zoneinfo/America/New_York.
  • If the path does not contain /zoneinfo/ (e.g. TZ=:/etc/localtime), the code falls through to the existing TZDEFAULT handling, which resolves the /etc/localtime symlink.
  • posix/ and right/ prefixes after /zoneinfo/ are skipped as elsewhere.
  • The fix applies on all platforms where CHECK_LOCALTIME_LINK is defined (Linux, macOS, BSD, Solaris), since their tzset() implementations also accept zoneinfo paths and extracting the ID is strictly better than returning a path that can never resolve to a zone.
  • Behaviour is unchanged for plain Olson IDs, PST8PDT style IDs, POSIX rule strings such as CST6CDT5,J129,J131/19:30, and unset TZ.

Tests

Added putiltst/TestTZNameEnv to cintltst. It is hermetic: uprv_tzname() extracts the ID from the path by string parsing without checking that the file exists, so the test uses fabricated paths and does not depend on the host's zoneinfo layout. Verified that the test fails with exactly the four path cases against unpatched putil.cpp and passes with the fix.

Also verified manually on Ubuntu 24.04 (glibc, arm64) and macOS with a matrix of 13 TZ values, cross-checked against glibc's own interpretation of each value, and ran intltest format/TimeZoneTest format/TimeZoneRuleTest format/TimeZoneFormatTest: all pass.

Checklist
  • Required: Issue filed: https://unicode-org.atlassian.net/browse/ICU-13694
  • Required: The PR title must be prefixed with a JIRA Issue number.
  • Required: The PR description must include the link to the Jira Issue, for example by completing the URL in the first checklist item
  • Required: Each commit message must be prefixed with a JIRA Issue number.
  • Issue accepted (done by Technical Committee after discussion)
  • Tests included, if applicable
  • API docs and/or User Guide docs changed or added, if applicable

On Linux with glibc (and other platforms with tzset()), the TZ environment
variable may be set to the full path of a zoneinfo file, with or without a
leading colon, e.g. TZ=:/usr/share/zoneinfo/America/New_York. Some Linux
distributions configure TZ this way, in which case ICU's host timezone
detection previously returned the whole path as the timezone ID and
detection failed.

Extract the Olson ID from the portion of the path following "/zoneinfo/",
mirroring the existing handling of the /etc/localtime symlink target. If TZ
points at a path without "/zoneinfo/" (e.g. TZ=:/etc/localtime), fall
through to the existing TZDEFAULT handling. The directories above the Olson
ID need not look like an Olson ID themselves (they may contain digits, e.g.
a tzdata version), so a path is recognized before the isValidOlsonID()
check. Add a cintltst test covering TZ handling in uprv_tzname().

Based on PR unicode-org#2213 by Jungshik Shin, rebased onto the current realpath-based
TZDEFAULT logic and restructured per review feedback.
@CLAassistant

CLAassistant commented Jul 6, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

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.

3 participants