From 1c09118fe14b0d4df3e8e65f1df3df6b44f4a663 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Helleu?= Date: Sat, 30 Aug 2025 18:55:46 +0200 Subject: [PATCH] api: allow lower characters "t" and "z" in function util_parse_time The following dates are now parsed with the same result: 2025-08-30T20:12:55.866643Z 2025-08-30t20:12:55.866643z --- CHANGELOG.md | 2 +- src/core/core-util.c | 34 ++++++++++++++++++++++++++++++ tests/unit/core/test-core-util.cpp | 3 +++ 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5882e28dd..a46d6ef3e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ SPDX-License-Identifier: GPL-3.0-or-later ### Changed -- api: add support of date like ISO 8601 but with spaces in function util_parse_time +- api: add support of date like ISO 8601 but with spaces and lower `t` and `z` in function util_parse_time - logger: use function util_parse_time to parse date/time in log files - build: require Curl ≥ 7.68.0 ([#2268](https://github.com/weechat/weechat/issues/2268)) - build: require GnuTLS ≥ 3.6.3 ([#2268](https://github.com/weechat/weechat/issues/2268)) diff --git a/src/core/core-util.c b/src/core/core-util.c index b3487fa99..129930b73 100644 --- a/src/core/core-util.c +++ b/src/core/core-util.c @@ -341,6 +341,8 @@ util_strftimeval (char *string, int max, const char *format, struct timeval *tv) * "1704402062.123456" -> timestamp date, microseconds * "1704402062,123456" -> timestamp date, microseconds * + * Note: lower characters "t" and "z" are also supported. + * * Returns: * 1: OK * 0: error @@ -439,6 +441,8 @@ util_parse_time (const char *datetime, struct timeval *tv) /* extract timezone and remove it from string */ pos = strrchr (string, 'Z'); + if (!pos) + pos = strrchr (string, 'z'); if (pos) { pos[0] = '\0'; @@ -448,6 +452,8 @@ util_parse_time (const char *datetime, struct timeval *tv) else { pos = strchr (string, 'T'); + if (!pos) + pos = strchr (string, 't'); if (!pos) pos = strchr (string, ' '); if (pos) @@ -522,6 +528,34 @@ util_parse_time (const char *datetime, struct timeval *tv) rc = 1; } } + else if (strchr (string, 't')) + { + /* ISO 8601 format like: "2024-01-04t21:01:02" */ + /* initialize structure, because strptime does not do it */ + memset (&tm_date, 0, sizeof (struct tm)); + pos = strptime (string, "%Y-%m-%dt%H:%M:%S", &tm_date); + if (pos && (tm_date.tm_year > 0)) + { + if (use_local_time) + { + tm_date.tm_isdst = -1; + tv->tv_sec = mktime (&tm_date); + } + else + { + /* convert to UTC and add timezone_offset */ + time_now = mktime (&tm_date); + gmtime_r (&time_now, &tm_date_gm); + localtime_r (&time_now, &tm_date_local); + time_gm = mktime (&tm_date_gm); + time_local = mktime (&tm_date_local); + tv->tv_sec = mktime (&tm_date_local) + + (time_local - time_gm) + - timezone_offset; + } + rc = 1; + } + } else { /* like ISO 8601 but with space like: "2024-01-04 21:01:02" */ diff --git a/tests/unit/core/test-core-util.cpp b/tests/unit/core/test-core-util.cpp index f175c2bf7..5b5afc2a0 100644 --- a/tests/unit/core/test-core-util.cpp +++ b/tests/unit/core/test-core-util.cpp @@ -386,9 +386,12 @@ TEST(CoreUtil, ParseTime) * expected: 2023-12-25T10:29:09.456789Z == 1703500149.456789 */ WEE_PARSE_DATE(1, 1703500149, 0, "2023-12-25T10:29:09"); + WEE_PARSE_DATE(1, 1703500149, 0, "2023-12-25t10:29:09"); WEE_PARSE_DATE(1, 1703500149, 0, "2023-12-25T10:29:09Z"); + WEE_PARSE_DATE(1, 1703500149, 0, "2023-12-25t10:29:09z"); WEE_PARSE_DATE(1, 1703500149, 456000, "2023-12-25T10:29:09.456Z"); WEE_PARSE_DATE(1, 1703500149, 456789, "2023-12-25T10:29:09.456789Z"); + WEE_PARSE_DATE(1, 1703500149, 456789, "2023-12-25t10:29:09.456789z"); /* * expected: 2023-12-25T10:29:09.456789Z == 1703500149.456789