From: Yu Watanabe Date: Tue, 9 Sep 2025 00:50:46 +0000 (+0900) Subject: time-util: introduce parse_gmtoff() helper function X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=23407c1806b037ce627a60d60df85a824b23967e;p=thirdparty%2Fsystemd.git time-util: introduce parse_gmtoff() helper function --- diff --git a/src/basic/time-util.c b/src/basic/time-util.c index bb5ba210b33..fa24d79d53e 100644 --- a/src/basic/time-util.c +++ b/src/basic/time-util.c @@ -624,6 +624,19 @@ char* format_timespan(char *buf, size_t l, usec_t t, usec_t accuracy) { return buf; } +int parse_gmtoff(const char *t, long *ret) { + assert(t); + + struct tm tm; + const char *k = strptime(t, "%z", &tm); + if (!k || *k != '\0') + return -EINVAL; + + if (ret) + *ret = tm.tm_gmtoff; + return 0; +} + static int parse_timestamp_impl( const char *t, size_t max_len, diff --git a/src/basic/time-util.h b/src/basic/time-util.h index da31e29f126..0c698eabd81 100644 --- a/src/basic/time-util.h +++ b/src/basic/time-util.h @@ -149,6 +149,7 @@ static inline char* format_timestamp(char *buf, size_t l, usec_t t) { #define FORMAT_TIMESTAMP_STYLE(t, style) \ format_timestamp_style((char[FORMAT_TIMESTAMP_MAX]){}, FORMAT_TIMESTAMP_MAX, t, style) +int parse_gmtoff(const char *t, long *ret); int parse_timestamp(const char *t, usec_t *ret); int parse_sec(const char *t, usec_t *ret); diff --git a/src/test/test-time-util.c b/src/test/test-time-util.c index b036f6aba5e..236a0ccbc41 100644 --- a/src/test/test-time-util.c +++ b/src/test/test-time-util.c @@ -663,6 +663,35 @@ TEST(format_timestamp_range) { test_format_timestamp_one(USEC_INFINITY, TIMESTAMP_UTC, NULL); } +TEST(parse_gmtoff) { + long t; + + ASSERT_OK(parse_gmtoff("+14", &t)); + ASSERT_EQ(t, (long) (14 * USEC_PER_HOUR / USEC_PER_SEC)); + ASSERT_OK(parse_gmtoff("-09", &t)); + ASSERT_EQ(t, - (long) (9 * USEC_PER_HOUR / USEC_PER_SEC)); + ASSERT_OK(parse_gmtoff("+1400", &t)); + ASSERT_EQ(t, (long) (14 * USEC_PER_HOUR / USEC_PER_SEC)); + ASSERT_OK(parse_gmtoff("-0900", &t)); + ASSERT_EQ(t, - (long) (9 * USEC_PER_HOUR / USEC_PER_SEC)); + ASSERT_OK(parse_gmtoff("+14:00", &t)); + ASSERT_EQ(t, (long) (14 * USEC_PER_HOUR / USEC_PER_SEC)); + ASSERT_OK(parse_gmtoff("-09:00", &t)); + ASSERT_EQ(t, - (long) (9 * USEC_PER_HOUR / USEC_PER_SEC)); + + ASSERT_ERROR(parse_gmtoff("", &t), EINVAL); + ASSERT_ERROR(parse_gmtoff("UTC", &t), EINVAL); + ASSERT_ERROR(parse_gmtoff("09", &t), EINVAL); + ASSERT_ERROR(parse_gmtoff("0900", &t), EINVAL); + ASSERT_ERROR(parse_gmtoff("?0900", &t), EINVAL); + ASSERT_ERROR(parse_gmtoff("?0900", &t), EINVAL); + ASSERT_ERROR(parse_gmtoff("+0900abc", &t), EINVAL); + ASSERT_ERROR(parse_gmtoff("+0900 ", &t), EINVAL); + ASSERT_ERROR(parse_gmtoff("+090000", &t), EINVAL); + ASSERT_ERROR(parse_gmtoff("+0900:00", &t), EINVAL); + ASSERT_ERROR(parse_gmtoff("+0900.00", &t), EINVAL); +} + static void test_parse_timestamp_one(const char *str, usec_t max_diff, usec_t expected) { usec_t usec = USEC_INFINITY; int r;