]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
time-util: introduce parse_gmtoff() helper function
authorYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 9 Sep 2025 00:50:46 +0000 (09:50 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Sat, 27 Sep 2025 02:52:24 +0000 (11:52 +0900)
src/basic/time-util.c
src/basic/time-util.h
src/test/test-time-util.c

index bb5ba210b336dcbdec3b41f42fb4b35f4fd112ab..fa24d79d53ea167714fe0332bf98e3a703e99926 100644 (file)
@@ -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,
index da31e29f1263f99136855bb6b78e8f9ef07e5892..0c698eabd816f6a1f0663568d664fd843e693ea2 100644 (file)
@@ -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);
index b036f6aba5e7666dfd81d8291b642e1beea258a1..236a0ccbc410b0039a3b1d2ddbe52d9f1fbbac32 100644 (file)
@@ -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;