Roundtripping server-time on non UTC breaks #980

Open
opened 2026-10-05 04:56:54 +02:00 by adam · 2 comments
Owner

If the system's timezone is not configured to UTC, then roundtripping server-time does not behave correctly. This can cause issues with playback replay when both the server, and the client are using server-time and the system TZ is set to something that isn't UTC.

Internally, the following should produce same result as the input regardless of TZ setting.

FormatServerTime(ParseServerTime("2011-10-19T16:40:51.620Z"))

Given the following patch to demonstrate:

diff --git a/test/UtilsTest.cpp b/test/UtilsTest.cpp
index 44514d98..e2f37c29 100644
--- a/test/UtilsTest.cpp
+++ b/test/UtilsTest.cpp
@@ -86,15 +86,16 @@ TEST(IRC32, SetMessageTags) {
 }
 
 TEST(UtilsTest, ServerTime) {
-    char* oldTZ = getenv("TZ");
-    if (oldTZ) oldTZ = strdup(oldTZ);
-    setenv("TZ", "UTC", 1);
-    tzset();
 
     timeval tv1 = CUtils::ParseServerTime("2011-10-19T16:40:51.620Z");
     CString str1 = CUtils::FormatServerTime(tv1);
     EXPECT_EQ(str1, "2011-10-19T16:40:51.620Z");
 
+    char* oldTZ = getenv("TZ");
+    if (oldTZ) oldTZ = strdup(oldTZ);
+    setenv("TZ", "UTC", 1);
+    tzset();
+
     timeval now = CUtils::GetTime();
 
     // Strip microseconds, server time is ms only

and then run:

$ env TZ=Europe/Prague make unittest

[ RUN      ] UtilsTest.ServerTime
../test/UtilsTest.cpp:92: Failure
Expected equality of these values:
  str1
    Which is: "2011-10-19T15:40:51.620Z"
  "2011-10-19T16:40:51.620Z"
    Which is: 0x477667c0174

The test case looks like it was implemented incorrectly, hiding this problem. Z in ISO 8601 should be UTC on both sides.

If the system's timezone is not configured to UTC, then roundtripping server-time does not behave correctly. This can cause issues with playback replay when both the server, and the client are using server-time and the system TZ is set to something that isn't UTC. Internally, the following should produce same result as the input regardless of TZ setting. ``` FormatServerTime(ParseServerTime("2011-10-19T16:40:51.620Z")) ``` Given the following patch to demonstrate: ```diff diff --git a/test/UtilsTest.cpp b/test/UtilsTest.cpp index 44514d98..e2f37c29 100644 --- a/test/UtilsTest.cpp +++ b/test/UtilsTest.cpp @@ -86,15 +86,16 @@ TEST(IRC32, SetMessageTags) { } TEST(UtilsTest, ServerTime) { - char* oldTZ = getenv("TZ"); - if (oldTZ) oldTZ = strdup(oldTZ); - setenv("TZ", "UTC", 1); - tzset(); timeval tv1 = CUtils::ParseServerTime("2011-10-19T16:40:51.620Z"); CString str1 = CUtils::FormatServerTime(tv1); EXPECT_EQ(str1, "2011-10-19T16:40:51.620Z"); + char* oldTZ = getenv("TZ"); + if (oldTZ) oldTZ = strdup(oldTZ); + setenv("TZ", "UTC", 1); + tzset(); + timeval now = CUtils::GetTime(); // Strip microseconds, server time is ms only ``` and then run: ``` $ env TZ=Europe/Prague make unittest [ RUN ] UtilsTest.ServerTime ../test/UtilsTest.cpp:92: Failure Expected equality of these values: str1 Which is: "2011-10-19T15:40:51.620Z" "2011-10-19T16:40:51.620Z" Which is: 0x477667c0174 ``` The test case looks like it was implemented incorrectly, hiding this problem. Z in ISO 8601 should be UTC on both sides. <!-- github-sync-id:812962620 -->
Author
Owner

I've experienced this issue myself, causing gaps in the playback log. I worked around the issue by setting Environment=TZ=Etc/UTC in the ZNC systemd service. It only happens on servers with the server-time extension (e.g. oragono) and only for received messages. Messages sent from ZNC are unaffected. With the playback module you can see this issue by running /msg *playback list. The last message timestamp will be offset by your timezone.

I've experienced this issue myself, causing gaps in the playback log. I worked around the issue by setting `Environment=TZ=Etc/UTC` in the ZNC systemd service. It only happens on servers with the `server-time` extension (e.g. oragono) and only for received messages. Messages sent from ZNC are unaffected. With the `playback` module you can see this issue by running `/msg *playback list`. The last message timestamp will be offset by your timezone. <!-- github-comment-id:782943874 -->
Author
Owner

May or may not be related to this bug, but setting Etc/UTC as the Timezone and applying @kylef's patch #1780, I was able to solve this problem as well.

I did run into a slight issue with clientbuffer, but I resolved it by deleting and remaking clients. Not elegant but it worked.

May or may not be related to this bug, but setting Etc/UTC as the Timezone and applying @kylef's patch #1780, I was able to solve this problem as well. I did run into a slight issue with clientbuffer, but I resolved it by deleting and remaking clients. Not elegant but it worked. <!-- github-comment-id:782980530 -->
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: adam/znc#980