The first patch is a prerequisite to fixing a GNU coreutils bug. It adds a posixtime_z function which operates on a timezone_t instead of the TZ environment variable.
The second patch adjusts the tests to use posixtime_z (NULL, ...), instead of setting the TZ environment variable. I'll push them tomorrow, unless anyone notices issues, of course. Collin
>From 13d584a701a6a0cef54a9c19a107417ae6753fc3 Mon Sep 17 00:00:00 2001 Message-ID: <13d584a701a6a0cef54a9c19a107417ae6753fc3.1792649557.git.collin.fu...@gmail.com> From: Collin Funk <[email protected]> Date: Wed, 21 Oct 2026 22:52:06 -0700 Subject: [PATCH 1/2] posixtm: Add posixtime_z which operates on a timezone_t. * lib/posixtm.c: Include stdlib.h. (year): Perform operations on a timezone_t argument. (posix_time_parse): Likewise. (posixtime_z): New function, based on the previous posixtime function but operating on a timezone_t. (posixtime): Implement in terms of posixtime_z. * lib/posixtm.h (posixtime_z): New declaration. * modules/posixtm (Depends-on): Add time_rz. --- ChangeLog | 12 ++++++++++++ lib/posixtm.c | 29 +++++++++++++++++++++-------- lib/posixtm.h | 2 ++ modules/posixtm | 1 + 4 files changed, 36 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index 70b2d84fde..a9a292f2a9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2026-10-21 Collin Funk <[email protected]> + + posixtm: Add posixtime_z which operates on a timezone_t. + * lib/posixtm.c: Include stdlib.h. + (year): Perform operations on a timezone_t argument. + (posix_time_parse): Likewise. + (posixtime_z): New function, based on the previous posixtime function + but operating on a timezone_t. + (posixtime): Implement in terms of posixtime_z. + * lib/posixtm.h (posixtime_z): New declaration. + * modules/posixtm (Depends-on): Add time_rz. + 2026-10-21 Bruno Haible <[email protected]> Avoid -Wundef warnings about __clang_major__ with recent GCC in C mode. diff --git a/lib/posixtm.c b/lib/posixtm.c index b5bb7afe9c..f6348fe786 100644 --- a/lib/posixtm.c +++ b/lib/posixtm.c @@ -27,6 +27,7 @@ #include "verify.h" #include <stdckdint.h> +#include <stdlib.h> #include <string.h> /* @@ -47,7 +48,8 @@ */ static bool -year (struct tm *tm, const int *digit_pair, idx_t n, unsigned int syntax_bits) +year (timezone_t tz, struct tm *tm, const int *digit_pair, idx_t n, + unsigned int syntax_bits) { switch (n) { @@ -74,7 +76,8 @@ year (struct tm *tm, const int *digit_pair, idx_t n, unsigned int syntax_bits) { /* Use current year. */ time_t now = time (NULL); - struct tm *tmp = localtime (&now); + struct tm tm_year; + struct tm *tmp = localtime_rz (tz, &now, &tm_year); if (! tmp) return false; tm->tm_year = tmp->tm_year; @@ -89,7 +92,8 @@ year (struct tm *tm, const int *digit_pair, idx_t n, unsigned int syntax_bits) } static bool -posix_time_parse (struct tm *tm, const char *s, unsigned int syntax_bits) +posix_time_parse (timezone_t tz, struct tm *tm, const char *s, + unsigned int syntax_bits) { idx_t s_len = strlen (s); @@ -123,7 +127,7 @@ posix_time_parse (struct tm *tm, const char *s, unsigned int syntax_bits) int *p = pair; if (! (syntax_bits & PDS_TRAILING_YEAR)) { - if (! year (tm, p, len - 4, syntax_bits)) + if (! year (tz, tm, p, len - 4, syntax_bits)) return false; p += len - 4; len = 4; @@ -139,7 +143,7 @@ posix_time_parse (struct tm *tm, const char *s, unsigned int syntax_bits) /* Handle any trailing year. */ if (syntax_bits & PDS_TRAILING_YEAR) { - if (! year (tm, p, len, syntax_bits)) + if (! year (tz, tm, p, len, syntax_bits)) return false; } @@ -157,11 +161,11 @@ posix_time_parse (struct tm *tm, const char *s, unsigned int syntax_bits) /* Parse a POSIX-style date, returning true if successful. */ bool -posixtime (time_t *p, const char *s, unsigned int syntax_bits) +posixtime_z (timezone_t tz, time_t *p, const char *s, unsigned int syntax_bits) { struct tm tm0; - if (! posix_time_parse (&tm0, s, syntax_bits)) + if (! posix_time_parse (tz, &tm0, s, syntax_bits)) return false; bool leapsec = false; @@ -176,7 +180,7 @@ posixtime (time_t *p, const char *s, unsigned int syntax_bits) tm1.tm_year = tm0.tm_year; tm1.tm_wday = -1; tm1.tm_isdst = -1; - time_t t = mktime (&tm1); + time_t t = mktime_z (tz, &tm1); if (tm1.tm_wday < 0) return false; @@ -207,3 +211,12 @@ posixtime (time_t *p, const char *s, unsigned int syntax_bits) leapsec = true; } } + +bool +posixtime (time_t *p, const char *s, unsigned int syntax_bits) +{ + timezone_t const tz = tzalloc (getenv ("TZ")); + if (! tz) + return false; + return posixtime_z (tz, p, s, syntax_bits); +} diff --git a/lib/posixtm.h b/lib/posixtm.h index 6c166dadb5..8bb023227b 100644 --- a/lib/posixtm.h +++ b/lib/posixtm.h @@ -39,6 +39,8 @@ extern "C" { #define PDS_LEADING_YEAR 0 bool posixtime (time_t *p, const char *s, unsigned int syntax_bits); +bool posixtime_z (timezone_t tz, time_t *p, const char *s, + unsigned int syntax_bits); #ifdef __cplusplus diff --git a/modules/posixtm b/modules/posixtm index e86912247c..84bccc42e3 100644 --- a/modules/posixtm +++ b/modules/posixtm @@ -13,6 +13,7 @@ mktime bool stdckdint-h time +time_rz verify configure.ac: -- 2.56.0
>From e2e40c9453074ba5aa19e5bd99cdbf5315060f09 Mon Sep 17 00:00:00 2001 Message-ID: <e2e40c9453074ba5aa19e5bd99cdbf5315060f09.1792649557.git.collin.fu...@gmail.com> In-Reply-To: <13d584a701a6a0cef54a9c19a107417ae6753fc3.1792649557.git.collin.fu...@gmail.com> References: <13d584a701a6a0cef54a9c19a107417ae6753fc3.1792649557.git.collin.fu...@gmail.com> From: Collin Funk <[email protected]> Date: Wed, 21 Oct 2026 23:06:20 -0700 Subject: [PATCH 2/2] posixtm tests: Use posixtime_z instead of setting TZ. * tests/test-posixtm.c (main): Operate on a NULL timezone_t instead of modifying environment variables. --- ChangeLog | 4 ++++ tests/test-posixtm.c | 17 ++++++----------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index a9a292f2a9..317fdd8a13 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2026-10-21 Collin Funk <[email protected]> + posixtm tests: Use posixtime_z instead of setting TZ. + * tests/test-posixtm.c (main): Operate on a NULL timezone_t instead of + modifying environment variables. + posixtm: Add posixtime_z which operates on a timezone_t. * lib/posixtm.c: Include stdlib.h. (year): Perform operations on a timezone_t argument. diff --git a/tests/test-posixtm.c b/tests/test-posixtm.c index 002aa705cb..3c42998890 100644 --- a/tests/test-posixtm.c +++ b/tests/test-posixtm.c @@ -119,20 +119,15 @@ int main (void) { char curr_year_str[30]; - struct tm *tm; time_t t_now; - int err; size_t n_bytes; - /* The above test data requires Universal Time, e.g., TZ="UTC0". */ - err = setenv ("TZ", "UTC0", 1); - ASSERT (err == 0); - t_now = time (NULL); ASSERT (t_now != (time_t) -1); - tm = localtime (&t_now); - ASSERT (tm); - n_bytes = strftime (curr_year_str, sizeof curr_year_str, "%Y", tm); + struct tm tm; + struct tm *tm_ptr = localtime_rz (NULL, &t_now, &tm); + ASSERT (tm_ptr); + n_bytes = strftime (curr_year_str, sizeof curr_year_str, "%Y", &tm); ASSERT (0 < n_bytes); for (unsigned int i = 0; T[i].in; i++) @@ -168,10 +163,10 @@ main (void) { char tmp_buf[20]; stpcpy (stpcpy (tmp_buf, curr_year_str), T[i].in); - ASSERT (posixtime (&t_exp, tmp_buf, T[i].syntax_bits)); + ASSERT (posixtime_z (NULL, &t_exp, tmp_buf, T[i].syntax_bits)); } - ok = posixtime (&t_out, T[i].in, T[i].syntax_bits); + ok = posixtime_z (NULL, &t_out, T[i].in, T[i].syntax_bits); if (ok != !!T[i].valid) { printf ("%s return value mismatch: got %d, expected %d\n", -- 2.56.0
