From bf53345f9ddae3e3d84ab34d8feb408c8f0dc8be Mon Sep 17 00:00:00 2001 From: xinsheng Ren <285808407@qq.com> Date: Tue, 11 Apr 2023 08:47:31 +0800 Subject: [PATCH] fix: windows gettime negative value (#20800) --- source/os/src/osTime.c | 33 +++++++-------- source/os/test/osTimeTests.cpp | 77 ++++++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+), 18 deletions(-) diff --git a/source/os/src/osTime.c b/source/os/src/osTime.c index f120b6650a..39d1de0437 100644 --- a/source/os/src/osTime.c +++ b/source/os/src/osTime.c @@ -37,6 +37,9 @@ // This magic number is the number of 100 nanosecond intervals since January 1, 1601 (UTC) // until 00:00:00 January 1, 1970 static const uint64_t TIMEEPOCH = ((uint64_t)116444736000000000ULL); +// This magic number is the number of 100 nanosecond intervals since January 1, 1601 (UTC) +// until 00:00:00 January 1, 1900 +static const uint64_t TIMEEPOCH1900 = ((uint64_t)116445024000000000ULL); /* * We do not implement alternate representations. However, we always @@ -409,7 +412,9 @@ time_t taosMktime(struct tm *timep) { struct tm *taosLocalTime(const time_t *timep, struct tm *result, char *buf) { struct tm *res = NULL; - + if (timep == NULL) { + return NULL; + } if (result == NULL) { res = localtime(timep); if (res == NULL && buf != NULL) { @@ -419,13 +424,15 @@ struct tm *taosLocalTime(const time_t *timep, struct tm *result, char *buf) { } #ifdef WINDOWS if (*timep < 0) { - if (buf != NULL) { - sprintf(buf, "NaN"); + if (*timep < -2208988800LL) { + if (buf != NULL) { + sprintf(buf, "NaN"); + } + return NULL; } - return NULL; - // TODO: bugs in following code - SYSTEMTIME ss, s; - FILETIME ff, f; + + SYSTEMTIME s; + FILETIME f; LARGE_INTEGER offset; struct tm tm1; time_t tt = 0; @@ -435,17 +442,7 @@ struct tm *taosLocalTime(const time_t *timep, struct tm *result, char *buf) { } return NULL; } - ss.wYear = tm1.tm_year + 1900; - ss.wMonth = tm1.tm_mon + 1; - ss.wDay = tm1.tm_mday; - ss.wHour = tm1.tm_hour; - ss.wMinute = tm1.tm_min; - ss.wSecond = tm1.tm_sec; - ss.wMilliseconds = 0; - SystemTimeToFileTime(&ss, &ff); - offset.QuadPart = ff.dwHighDateTime; - offset.QuadPart <<= 32; - offset.QuadPart |= ff.dwLowDateTime; + offset.QuadPart = TIMEEPOCH1900; offset.QuadPart += *timep * 10000000; f.dwLowDateTime = offset.QuadPart & 0xffffffff; f.dwHighDateTime = (offset.QuadPart >> 32) & 0xffffffff; diff --git a/source/os/test/osTimeTests.cpp b/source/os/test/osTimeTests.cpp index 366c3fc720..5dd15db4ab 100644 --- a/source/os/test/osTimeTests.cpp +++ b/source/os/test/osTimeTests.cpp @@ -46,3 +46,80 @@ TEST(osTimeTests, taosLocalTimeNolock) { EXPECT_EQ(expectedTime.tm_yday, result->tm_yday); EXPECT_EQ(expectedTime.tm_isdst, result->tm_isdst); } + + +TEST(osTimeTests, taosLocalTime) { + // Test 1: Test when both timep and result are not NULL + time_t timep = 1617531000; // 2021-04-04 18:10:00 + struct tm result; + struct tm* local_time = taosLocalTime(&timep, &result, NULL); + ASSERT_NE(local_time, nullptr); + ASSERT_EQ(local_time->tm_year, 121); + ASSERT_EQ(local_time->tm_mon, 3); + ASSERT_EQ(local_time->tm_mday, 4); + ASSERT_EQ(local_time->tm_hour, 18); + ASSERT_EQ(local_time->tm_min, 10); + ASSERT_EQ(local_time->tm_sec, 00); + + // Test 2: Test when timep is NULL + local_time = taosLocalTime(NULL, &result, NULL); + ASSERT_EQ(local_time, nullptr); + + // Test 3: Test when result is NULL + local_time = taosLocalTime(&timep, NULL, NULL); + ASSERT_NE(local_time, nullptr); + ASSERT_EQ(local_time->tm_year, 121); + ASSERT_EQ(local_time->tm_mon, 3); + ASSERT_EQ(local_time->tm_mday, 4); + + // Test 4: Test when timep is negative on Windows +#ifdef WINDOWS + time_t pos_timep = 1609459200; // 2021-01-01 08:00:00 + local_time = taosLocalTime(&pos_timep, &result, NULL); + ASSERT_NE(local_time, nullptr); + ASSERT_EQ(local_time->tm_year, 121); + ASSERT_EQ(local_time->tm_mon, 0); + ASSERT_EQ(local_time->tm_mday, 1); + ASSERT_EQ(local_time->tm_hour, 8); + ASSERT_EQ(local_time->tm_min, 0); + ASSERT_EQ(local_time->tm_sec, 0); + + time_t neg_timep = -1617531000; // 1918-09-29 21:50:00 + local_time = taosLocalTime(&neg_timep, &result, NULL); + ASSERT_NE(local_time, nullptr); + ASSERT_EQ(local_time->tm_year, 18); + ASSERT_EQ(local_time->tm_mon, 8); + ASSERT_EQ(local_time->tm_mday, 29); + ASSERT_EQ(local_time->tm_hour, 21); + ASSERT_EQ(local_time->tm_min, 50); + ASSERT_EQ(local_time->tm_sec, 0); + + time_t neg_timep2 = -315619200; // 1960-01-01 08:00:00 + local_time = taosLocalTime(&neg_timep2, &result, NULL); + ASSERT_NE(local_time, nullptr); + ASSERT_EQ(local_time->tm_year, 60); + ASSERT_EQ(local_time->tm_mon, 0); + ASSERT_EQ(local_time->tm_mday, 1); + ASSERT_EQ(local_time->tm_hour, 8); + ASSERT_EQ(local_time->tm_min, 0); + ASSERT_EQ(local_time->tm_sec, 0); + + time_t zero_timep = 0; // 1970-01-01 08:00:00 + local_time = taosLocalTime(&zero_timep, &result, NULL); + ASSERT_NE(local_time, nullptr); + ASSERT_EQ(local_time->tm_year, 70); + ASSERT_EQ(local_time->tm_mon, 0); + ASSERT_EQ(local_time->tm_mday, 1); + ASSERT_EQ(local_time->tm_hour, 8); + ASSERT_EQ(local_time->tm_min, 0); + ASSERT_EQ(local_time->tm_sec, 0); + + time_t over_timep = 6406301441633558; + local_time = taosLocalTime(&over_timep, &result, NULL); + ASSERT_EQ(local_time, nullptr); + + time_t neg_timep3 = -78115158887; + local_time = taosLocalTime(&neg_timep3, &result, NULL); + ASSERT_EQ(local_time, nullptr); +#endif +} \ No newline at end of file -- GitLab