From 51f448ba2467012dddc0ec7eca9b5504d95bd80f Mon Sep 17 00:00:00 2001 From: Eugenio Collado Date: Tue, 11 Feb 2025 15:43:46 +0100 Subject: [PATCH 1/8] fix time utils overflow in windows Signed-off-by: Eugenio Collado --- .../include/cpp_utils/time/time_utils.hpp | 3 +- cpp_utils/src/cpp/time/time_utils.cpp | 28 +++++++--- .../test/unittest/time/time_utils_test.cpp | 53 ++++++++++++++++++- 3 files changed, 73 insertions(+), 11 deletions(-) diff --git a/cpp_utils/include/cpp_utils/time/time_utils.hpp b/cpp_utils/include/cpp_utils/time/time_utils.hpp index 31818a50..80f4119b 100644 --- a/cpp_utils/include/cpp_utils/time/time_utils.hpp +++ b/cpp_utils/include/cpp_utils/time/time_utils.hpp @@ -32,7 +32,8 @@ using Duration_ms = uint32_t; /** * Type used to represent time points */ -using Timestamp = std::chrono::time_point; +using Timeclock = std::chrono::system_clock; +using Timestamp = std::chrono::time_point; /** * @brief Now time diff --git a/cpp_utils/src/cpp/time/time_utils.cpp b/cpp_utils/src/cpp/time/time_utils.cpp index 6a461719..4a936a8b 100644 --- a/cpp_utils/src/cpp/time/time_utils.cpp +++ b/cpp_utils/src/cpp/time/time_utils.cpp @@ -36,17 +36,25 @@ namespace utils { Timestamp now() noexcept { - return std::chrono::system_clock::now(); + return Timeclock::now(); } Timestamp the_end_of_time() noexcept { - return std::chrono::time_point::max(); + #if defined(_WIN32) // In Windows std::gmtime does not support negative values nor values greater than 2^32 + return Timeclock::from_time_t(std::numeric_limits::max()); + #else + return Timestamp::max(); + #endif // if defined(_WIN32) } Timestamp the_beginning_of_time() noexcept { - return std::chrono::time_point::min(); + #if defined(_WIN32) // In Windows std::gmtime does not support negative values nor values greater than 2^32 + return Timeclock::from_time_t(0); + #else + return Timestamp::min(); + #endif // if defined(_WIN32) } Timestamp date_to_timestamp( @@ -66,7 +74,7 @@ Timestamp date_to_timestamp( tm.tm_mon = static_cast(month) - 1; tm.tm_year = static_cast(year) - 1900; - return std::chrono::system_clock::from_time_t(timegm(&tm)); + return Timeclock::from_time_t(timegm(&tm)); } Timestamp time_to_timestamp( @@ -86,7 +94,7 @@ Timestamp time_to_timestamp( tm.tm_min = static_cast(minute); tm.tm_hour = static_cast(hour); - return std::chrono::system_clock::from_time_t(timegm(&tm)); + return Timeclock::from_time_t(timegm(&tm)); } std::string timestamp_to_string( @@ -95,8 +103,12 @@ std::string timestamp_to_string( bool local_time /* = false */) { std::ostringstream ss; - const std::chrono::high_resolution_clock::time_point::duration duration = timestamp.time_since_epoch(); - const time_t duration_seconds = std::chrono::duration_cast(duration).count(); + time_t duration_seconds = std::chrono::duration_cast(timestamp.time_since_epoch()).count(); + + #if defined(_WIN32) // In Windows std::gmtime does not support negative values nor values greater than 2^32 + time_t max_value = std::numeric_limits::max(); + duration_seconds = std::max((time_t) 0, std::min(max_value, duration_seconds)); + #endif // if defined(_WIN32) std::tm* tm = nullptr; if (local_time) @@ -153,7 +165,7 @@ Timestamp string_to_timestamp( { utc_time = timegm(&tm); } - return std::chrono::system_clock::from_time_t(utc_time); + return Timeclock::from_time_t(utc_time); } std::chrono::milliseconds duration_to_ms( diff --git a/cpp_utils/test/unittest/time/time_utils_test.cpp b/cpp_utils/test/unittest/time/time_utils_test.cpp index 530fcc85..aabfe808 100644 --- a/cpp_utils/test/unittest/time/time_utils_test.cpp +++ b/cpp_utils/test/unittest/time/time_utils_test.cpp @@ -31,8 +31,11 @@ using namespace eprosima::utils; * - now * - now with alternative format * - old time + * - the beginning of time * - future time + * - the end of time * - some time today + * - wrong date and time */ TEST(time_utils_test, timestamp_to_string_to_timestamp) { @@ -112,14 +115,37 @@ TEST(time_utils_test, timestamp_to_string_to_timestamp) ASSERT_EQ(timestamp_to_string(old_time_from_str), expected_string_os.str()); } + // the begininng of time + { + Timestamp beginning_time = the_beginning_of_time(); + std::string beginning_time_str = timestamp_to_string(beginning_time); + + std::ostringstream expected_string_os; + expected_string_os + << 1970 + << "-" << "01" + << "-" << "01" + << "_" << "00" + << "-" << "00" + << "-" << "00"; + + // Test timestamp_to_string + ASSERT_EQ(beginning_time_str, expected_string_os.str()); + + // Test string_to_timestamp + Timestamp beginning_time_from_str = string_to_timestamp(beginning_time_str); + // NOTE: cannot directly compare timestamps because some precision is lost during ts->str conversion + ASSERT_EQ(timestamp_to_string(beginning_time_from_str), expected_string_os.str()); + } + // future time { - Timestamp future_time = date_to_timestamp(2233u, 5u, 22u); + Timestamp future_time = date_to_timestamp(2033u, 5u, 22u); std::string future_time_str = timestamp_to_string(future_time); std::ostringstream expected_string_os; expected_string_os - << 2233 + << 2033 << "-" << "05" << "-" << 22 << "_" << "00" @@ -135,6 +161,29 @@ TEST(time_utils_test, timestamp_to_string_to_timestamp) ASSERT_EQ(timestamp_to_string(future_time_from_str), expected_string_os.str()); } + // the end of time + { + Timestamp end_time = the_end_of_time(); + std::string end_time_str = timestamp_to_string(end_time); + + std::ostringstream expected_string_os; + expected_string_os + << 2038 + << "-" << "01" + << "-" << 19 + << "_" << "03" + << "-" << "14" + << "-" << "07"; + + // Test timestamp_to_string + ASSERT_EQ(end_time_str, expected_string_os.str()); + + // Test string_to_timestamp + Timestamp end_time_from_str = string_to_timestamp(end_time_str); + // NOTE: cannot directly compare timestamps because some precision is lost during ts->str conversion + ASSERT_EQ(timestamp_to_string(end_time_from_str), expected_string_os.str()); + } + // some time today { Timestamp some_time_today = time_to_timestamp(13u, 13u, 13u); From 523e97c35b3bc09122c3f9b99e3a242f11c06cf5 Mon Sep 17 00:00:00 2001 From: Eugenio Collado Date: Wed, 12 Feb 2025 09:01:33 +0100 Subject: [PATCH 2/8] Fix tests for ubuntu and changed to _EPROSIMA_WINDOWS_PLATFORM macro Signed-off-by: Eugenio Collado --- cpp_utils/src/cpp/time/time_utils.cpp | 12 +++++----- .../test/unittest/time/time_utils_test.cpp | 24 ++++++++++++++++++- 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/cpp_utils/src/cpp/time/time_utils.cpp b/cpp_utils/src/cpp/time/time_utils.cpp index 4a936a8b..65f8fcad 100644 --- a/cpp_utils/src/cpp/time/time_utils.cpp +++ b/cpp_utils/src/cpp/time/time_utils.cpp @@ -41,20 +41,20 @@ Timestamp now() noexcept Timestamp the_end_of_time() noexcept { - #if defined(_WIN32) // In Windows std::gmtime does not support negative values nor values greater than 2^32 + #if _EPROSIMA_WINDOWS_PLATFORM // In Windows std::gmtime does not support negative values nor values greater than 2^32 return Timeclock::from_time_t(std::numeric_limits::max()); #else return Timestamp::max(); - #endif // if defined(_WIN32) + #endif // if _EPROSIMA_WINDOWS_PLATFORM } Timestamp the_beginning_of_time() noexcept { - #if defined(_WIN32) // In Windows std::gmtime does not support negative values nor values greater than 2^32 + #if _EPROSIMA_WINDOWS_PLATFORM // In Windows std::gmtime does not support negative values nor values greater than 2^32 return Timeclock::from_time_t(0); #else return Timestamp::min(); - #endif // if defined(_WIN32) + #endif // if _EPROSIMA_WINDOWS_PLATFORM } Timestamp date_to_timestamp( @@ -105,10 +105,10 @@ std::string timestamp_to_string( std::ostringstream ss; time_t duration_seconds = std::chrono::duration_cast(timestamp.time_since_epoch()).count(); - #if defined(_WIN32) // In Windows std::gmtime does not support negative values nor values greater than 2^32 + #if _EPROSIMA_WINDOWS_PLATFORM // In Windows std::gmtime does not support negative values nor values greater than 2^32 time_t max_value = std::numeric_limits::max(); duration_seconds = std::max((time_t) 0, std::min(max_value, duration_seconds)); - #endif // if defined(_WIN32) + #endif // if _EPROSIMA_WINDOWS_PLATFORM std::tm* tm = nullptr; if (local_time) diff --git a/cpp_utils/test/unittest/time/time_utils_test.cpp b/cpp_utils/test/unittest/time/time_utils_test.cpp index aabfe808..43c3f1c1 100644 --- a/cpp_utils/test/unittest/time/time_utils_test.cpp +++ b/cpp_utils/test/unittest/time/time_utils_test.cpp @@ -97,7 +97,7 @@ TEST(time_utils_test, timestamp_to_string_to_timestamp) Timestamp old_time = date_to_timestamp(1970u, 7u, 20u, 6u, 39u, 42u); std::string old_time_str = timestamp_to_string(old_time); - std::ostringstream expected_string_os; + std::ostringstream expected_string_os; expected_string_os << 1970 << "-" << "07" @@ -121,6 +121,7 @@ TEST(time_utils_test, timestamp_to_string_to_timestamp) std::string beginning_time_str = timestamp_to_string(beginning_time); std::ostringstream expected_string_os; + #if _EPROSIMA_WINDOWS_PLATFORM expected_string_os << 1970 << "-" << "01" @@ -128,6 +129,16 @@ TEST(time_utils_test, timestamp_to_string_to_timestamp) << "_" << "00" << "-" << "00" << "-" << "00"; + #else //1677-09-21_00-12-44 + expected_string_os + << 1677 + << "-" << "09" + << "-" << "21" + << "_" << "00" + << "-" << "12" + << "-" << "44"; + #endif // _EPROSIMA_WINDOWS_PLATFORM + // Test timestamp_to_string ASSERT_EQ(beginning_time_str, expected_string_os.str()); @@ -167,6 +178,7 @@ TEST(time_utils_test, timestamp_to_string_to_timestamp) std::string end_time_str = timestamp_to_string(end_time); std::ostringstream expected_string_os; + #if _EPROSIMA_WINDOWS_PLATFORM expected_string_os << 2038 << "-" << "01" @@ -174,6 +186,16 @@ TEST(time_utils_test, timestamp_to_string_to_timestamp) << "_" << "03" << "-" << "14" << "-" << "07"; + #else // 2262-04-11 23:47:16 + expected_string_os + << 2262 + << "-" << "04" + << "-" << 11 + << "_" << "23" + << "-" << "47" + << "-" << "16"; + #endif // _EPROSIMA_WINDOWS_PLATFORM + // Test timestamp_to_string ASSERT_EQ(end_time_str, expected_string_os.str()); From 8a5911820a6096d522aeb57fe712c085d251e944 Mon Sep 17 00:00:00 2001 From: Eugenio Collado Date: Wed, 12 Feb 2025 09:32:36 +0100 Subject: [PATCH 3/8] Uncrustify Signed-off-by: Eugenio Collado --- cpp_utils/test/unittest/time/time_utils_test.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cpp_utils/test/unittest/time/time_utils_test.cpp b/cpp_utils/test/unittest/time/time_utils_test.cpp index 43c3f1c1..a6a84934 100644 --- a/cpp_utils/test/unittest/time/time_utils_test.cpp +++ b/cpp_utils/test/unittest/time/time_utils_test.cpp @@ -97,7 +97,7 @@ TEST(time_utils_test, timestamp_to_string_to_timestamp) Timestamp old_time = date_to_timestamp(1970u, 7u, 20u, 6u, 39u, 42u); std::string old_time_str = timestamp_to_string(old_time); - std::ostringstream expected_string_os; + std::ostringstream expected_string_os; expected_string_os << 1970 << "-" << "07" @@ -138,7 +138,7 @@ TEST(time_utils_test, timestamp_to_string_to_timestamp) << "-" << "12" << "-" << "44"; #endif // _EPROSIMA_WINDOWS_PLATFORM - + // Test timestamp_to_string ASSERT_EQ(beginning_time_str, expected_string_os.str()); @@ -195,7 +195,7 @@ TEST(time_utils_test, timestamp_to_string_to_timestamp) << "-" << "47" << "-" << "16"; #endif // _EPROSIMA_WINDOWS_PLATFORM - + // Test timestamp_to_string ASSERT_EQ(end_time_str, expected_string_os.str()); From d7f2d7c666cffcf49c4cb6dfcada6a575506c5b3 Mon Sep 17 00:00:00 2001 From: Eugenio Collado Date: Thu, 13 Feb 2025 15:28:55 +0100 Subject: [PATCH 4/8] Applied suggestions Signed-off-by: Eugenio Collado --- .../include/cpp_utils/time/time_utils.hpp | 6 +- cpp_utils/src/cpp/time/time_utils.cpp | 18 +++-- .../test/unittest/time/time_utils_test.cpp | 69 ++++++++++++++++++- 3 files changed, 81 insertions(+), 12 deletions(-) diff --git a/cpp_utils/include/cpp_utils/time/time_utils.hpp b/cpp_utils/include/cpp_utils/time/time_utils.hpp index 80f4119b..1d1c38b5 100644 --- a/cpp_utils/include/cpp_utils/time/time_utils.hpp +++ b/cpp_utils/include/cpp_utils/time/time_utils.hpp @@ -30,9 +30,13 @@ namespace utils { using Duration_ms = uint32_t; /** - * Type used to represent time points + * Type used to fix the clock to the system clock */ using Timeclock = std::chrono::system_clock; + +/** + * Type used to represent time points + */ using Timestamp = std::chrono::time_point; /** diff --git a/cpp_utils/src/cpp/time/time_utils.cpp b/cpp_utils/src/cpp/time/time_utils.cpp index 65f8fcad..40cc1ed8 100644 --- a/cpp_utils/src/cpp/time/time_utils.cpp +++ b/cpp_utils/src/cpp/time/time_utils.cpp @@ -41,20 +41,12 @@ Timestamp now() noexcept Timestamp the_end_of_time() noexcept { - #if _EPROSIMA_WINDOWS_PLATFORM // In Windows std::gmtime does not support negative values nor values greater than 2^32 - return Timeclock::from_time_t(std::numeric_limits::max()); - #else return Timestamp::max(); - #endif // if _EPROSIMA_WINDOWS_PLATFORM } Timestamp the_beginning_of_time() noexcept { - #if _EPROSIMA_WINDOWS_PLATFORM // In Windows std::gmtime does not support negative values nor values greater than 2^32 - return Timeclock::from_time_t(0); - #else return Timestamp::min(); - #endif // if _EPROSIMA_WINDOWS_PLATFORM } Timestamp date_to_timestamp( @@ -106,8 +98,14 @@ std::string timestamp_to_string( time_t duration_seconds = std::chrono::duration_cast(timestamp.time_since_epoch()).count(); #if _EPROSIMA_WINDOWS_PLATFORM // In Windows std::gmtime does not support negative values nor values greater than 2^32 - time_t max_value = std::numeric_limits::max(); - duration_seconds = std::max((time_t) 0, std::min(max_value, duration_seconds)); + time_t max_value = std::numeric_limits::max(); + if (0 > duration_seconds || duration_seconds > max_value) + { + EPROSIMA_LOG_WARNING(TIME_UTILS, + "Timestamp value: " << duration_seconds << " is out of range for Windows, clamping to 0 and " << + max_value); + duration_seconds = std::max((time_t) 0, std::min(max_value, duration_seconds)); + } #endif // if _EPROSIMA_WINDOWS_PLATFORM std::tm* tm = nullptr; diff --git a/cpp_utils/test/unittest/time/time_utils_test.cpp b/cpp_utils/test/unittest/time/time_utils_test.cpp index a6a84934..7c4fef94 100644 --- a/cpp_utils/test/unittest/time/time_utils_test.cpp +++ b/cpp_utils/test/unittest/time/time_utils_test.cpp @@ -31,11 +31,12 @@ using namespace eprosima::utils; * - now * - now with alternative format * - old time + * - date before 1970 * - the beginning of time * - future time + * - date after 2038 * - the end of time * - some time today - * - wrong date and time */ TEST(time_utils_test, timestamp_to_string_to_timestamp) { @@ -115,6 +116,39 @@ TEST(time_utils_test, timestamp_to_string_to_timestamp) ASSERT_EQ(timestamp_to_string(old_time_from_str), expected_string_os.str()); } + // date before 1970 + { + Timestamp old_time = date_to_timestamp(1959u, 7u, 20u, 6u, 39u, 42u); + std::string old_time_str = timestamp_to_string(old_time); + + std::ostringstream expected_string_os; + #if _EPROSIMA_WINDOWS_PLATFORM + expected_string_os + << 1970 + << "-" << "01" + << "-" << "01" + << "_" << "00" + << "-" << "00" + << "-" << "00"; + #else + expected_string_os + << 1959 + << "-" << "07" + << "-" << 20 + << "_" << "06" + << "-" << 39 + << "-" << 42; + #endif // _EPROSIMA_WINDOWS_PLATFORM + + // Test timestamp_to_string + ASSERT_EQ(old_time_str, expected_string_os.str()); + + // Test string_to_timestamp + Timestamp old_time_from_str = string_to_timestamp(old_time_str); + // NOTE: cannot directly compare timestamps because some precision is lost during ts->str conversion + ASSERT_EQ(timestamp_to_string(old_time_from_str), expected_string_os.str()); + } + // the begininng of time { Timestamp beginning_time = the_beginning_of_time(); @@ -172,6 +206,39 @@ TEST(time_utils_test, timestamp_to_string_to_timestamp) ASSERT_EQ(timestamp_to_string(future_time_from_str), expected_string_os.str()); } + // date after 2038 + { + Timestamp future_time = date_to_timestamp(2049u, 5u, 22u); + std::string future_time_str = timestamp_to_string(future_time); + + std::ostringstream expected_string_os; + #if _EPROSIMA_WINDOWS_PLATFORM + expected_string_os + << 2038 + << "-" << "01" + << "-" << 19 + << "_" << "03" + << "-" << "14" + << "-" << "07"; + #else + expected_string_os + << 2049 + << "-" << "05" + << "-" << 22 + << "_" << "00" + << "-" << "00" + << "-" << "00"; + #endif // _EPROSIMA_WINDOWS_PLATFORM + + // Test timestamp_to_string + ASSERT_EQ(future_time_str, expected_string_os.str()); + + // Test string_to_timestamp + Timestamp future_time_from_str = string_to_timestamp(future_time_str); + // NOTE: cannot directly compare timestamps because some precision is lost during ts->str conversion + ASSERT_EQ(timestamp_to_string(future_time_from_str), expected_string_os.str()); + } + // the end of time { Timestamp end_time = the_end_of_time(); From fd2bc65002ff7ce4cf96fba84d1a7ab70ba7ab4d Mon Sep 17 00:00:00 2001 From: Mario Dominguez Date: Wed, 2 Jul 2025 08:01:34 +0200 Subject: [PATCH 5/8] Refs #23440: Add new _PLAFORM_32/64 BITS Signed-off-by: Mario Dominguez --- cpp_utils/include/cpp_utils/macros/macros.hpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/cpp_utils/include/cpp_utils/macros/macros.hpp b/cpp_utils/include/cpp_utils/macros/macros.hpp index 2bd7c3d2..69b6843d 100644 --- a/cpp_utils/include/cpp_utils/macros/macros.hpp +++ b/cpp_utils/include/cpp_utils/macros/macros.hpp @@ -87,5 +87,11 @@ namespace utils { #define _EPROSIMA_WINDOWS_PLATFORM 1 #endif // if defined(WIN32) || defined(_WIN32) || defined(__WIN32) || defined(WIN64) || defined(_WIN64) || defined(__WIN64) || defined(_MSC_VER) +#if defined(WIN64) || defined(_WIN64) || defined(__WIN64) || defined(_WIN64) || defined(__x86_64__) || defined(__ppc64__) || defined(__aarch64__) +#define _PLATFORM_64BIT 1 +#else +#define _PLATFORM_32BIT 1 +#endif + } /* namespace utils */ } /* namespace eprosima */ From 72a043dd8a9c7459967ffbc365058a769869f163 Mon Sep 17 00:00:00 2001 From: Mario Dominguez Date: Wed, 2 Jul 2025 08:02:37 +0200 Subject: [PATCH 6/8] Refs #23440: normalize(time_t) method Signed-off-by: Mario Dominguez --- .../include/cpp_utils/time/time_utils.hpp | 12 +++++ cpp_utils/src/cpp/time/time_utils.cpp | 51 +++++++++++++------ 2 files changed, 47 insertions(+), 16 deletions(-) diff --git a/cpp_utils/include/cpp_utils/time/time_utils.hpp b/cpp_utils/include/cpp_utils/time/time_utils.hpp index 1d1c38b5..7e41226a 100644 --- a/cpp_utils/include/cpp_utils/time/time_utils.hpp +++ b/cpp_utils/include/cpp_utils/time/time_utils.hpp @@ -103,5 +103,17 @@ CPP_UTILS_DllAPI std::chrono::milliseconds duration_to_ms( CPP_UTILS_DllAPI void sleep_for( const Duration_ms& sleep_time) noexcept; +/** + * @brief Makes sure that the time is clamped into a valid range. + * This is useful for keeping time values within the ranges + * depending on the platform. + * + * @param time time to normalize. + * + * @return normalized time value. + */ +CPP_UTILS_DllAPI time_t normalize( + const time_t& time) noexcept; + } /* namespace utils */ } /* namespace eprosima */ diff --git a/cpp_utils/src/cpp/time/time_utils.cpp b/cpp_utils/src/cpp/time/time_utils.cpp index 40cc1ed8..bb68af16 100644 --- a/cpp_utils/src/cpp/time/time_utils.cpp +++ b/cpp_utils/src/cpp/time/time_utils.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include // These functions has different names in windows @@ -66,7 +67,7 @@ Timestamp date_to_timestamp( tm.tm_mon = static_cast(month) - 1; tm.tm_year = static_cast(year) - 1900; - return Timeclock::from_time_t(timegm(&tm)); + return Timeclock::from_time_t(normalize(timegm(&tm))); } Timestamp time_to_timestamp( @@ -77,9 +78,7 @@ Timestamp time_to_timestamp( std::tm tm; // Initialise with current timestamp to set date - auto current_ts = now(); - std::chrono::high_resolution_clock::time_point::duration duration = current_ts.time_since_epoch(); - time_t duration_seconds = std::chrono::duration_cast(duration).count(); + time_t duration_seconds = normalize(Timeclock::to_time_t(now())); tm = *std::gmtime(&duration_seconds); tm.tm_sec = static_cast(second); @@ -95,18 +94,7 @@ std::string timestamp_to_string( bool local_time /* = false */) { std::ostringstream ss; - time_t duration_seconds = std::chrono::duration_cast(timestamp.time_since_epoch()).count(); - - #if _EPROSIMA_WINDOWS_PLATFORM // In Windows std::gmtime does not support negative values nor values greater than 2^32 - time_t max_value = std::numeric_limits::max(); - if (0 > duration_seconds || duration_seconds > max_value) - { - EPROSIMA_LOG_WARNING(TIME_UTILS, - "Timestamp value: " << duration_seconds << " is out of range for Windows, clamping to 0 and " << - max_value); - duration_seconds = std::max((time_t) 0, std::min(max_value, duration_seconds)); - } - #endif // if _EPROSIMA_WINDOWS_PLATFORM + time_t duration_seconds = normalize(Timeclock::to_time_t(timestamp)); std::tm* tm = nullptr; if (local_time) @@ -163,6 +151,13 @@ Timestamp string_to_timestamp( { utc_time = timegm(&tm); } + + if ((time_t)-1 == utc_time) + { + throw ValueNotAllowedException( + STR_ENTRY << "Failed to convert string to timestamp"); + } + return Timeclock::from_time_t(utc_time); } @@ -178,5 +173,29 @@ void sleep_for( std::this_thread::sleep_for(duration_to_ms(sleep_time)); } +time_t normalize( + const time_t& time) noexcept +{ + time_t normalized_time = time; +#if _EPROSIMA_WINDOWS_PLATFORM // In Windows std::gmtime does not support negative values + time_t max_value; + +#if _PLATFORM_64BIT + max_value = 32535215999; // In WIN64, max value is 3000-12-31_23-59-59 +#else + max_value = std::numeric_limits::max(); // In WIN32, values greater than 2^32 are not supported +#endif // if PLATFORM_64BIT + + if (0 > time || time > max_value) + { + EPROSIMA_LOG_WARNING(TIME_UTILS, + "Timestamp value: " << time << " is out of range for Windows, clamping to 0 and " << + max_value); + normalized_time = std::max((time_t) 0, std::min(max_value, time)); + } +#endif // if _EPROSIMA_WINDOWS_PLATFORM + return normalized_time; +} + } /* namespace utils */ } /* namespace eprosima */ From ecd49085abbce1194978efb31cb29a00a73d1e89 Mon Sep 17 00:00:00 2001 From: Mario Dominguez Date: Wed, 2 Jul 2025 08:02:52 +0200 Subject: [PATCH 7/8] Refs #23440: update tests Signed-off-by: Mario Dominguez --- .../test/unittest/time/time_utils_test.cpp | 32 ++++++++++++------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/cpp_utils/test/unittest/time/time_utils_test.cpp b/cpp_utils/test/unittest/time/time_utils_test.cpp index 7c4fef94..0121c0fd 100644 --- a/cpp_utils/test/unittest/time/time_utils_test.cpp +++ b/cpp_utils/test/unittest/time/time_utils_test.cpp @@ -122,7 +122,7 @@ TEST(time_utils_test, timestamp_to_string_to_timestamp) std::string old_time_str = timestamp_to_string(old_time); std::ostringstream expected_string_os; - #if _EPROSIMA_WINDOWS_PLATFORM +#if _EPROSIMA_WINDOWS_PLATFORM expected_string_os << 1970 << "-" << "01" @@ -130,7 +130,7 @@ TEST(time_utils_test, timestamp_to_string_to_timestamp) << "_" << "00" << "-" << "00" << "-" << "00"; - #else +#else expected_string_os << 1959 << "-" << "07" @@ -138,7 +138,7 @@ TEST(time_utils_test, timestamp_to_string_to_timestamp) << "_" << "06" << "-" << 39 << "-" << 42; - #endif // _EPROSIMA_WINDOWS_PLATFORM +#endif // _EPROSIMA_WINDOWS_PLATFORM // Test timestamp_to_string ASSERT_EQ(old_time_str, expected_string_os.str()); @@ -155,7 +155,7 @@ TEST(time_utils_test, timestamp_to_string_to_timestamp) std::string beginning_time_str = timestamp_to_string(beginning_time); std::ostringstream expected_string_os; - #if _EPROSIMA_WINDOWS_PLATFORM +#if _EPROSIMA_WINDOWS_PLATFORM expected_string_os << 1970 << "-" << "01" @@ -163,7 +163,7 @@ TEST(time_utils_test, timestamp_to_string_to_timestamp) << "_" << "00" << "-" << "00" << "-" << "00"; - #else //1677-09-21_00-12-44 +#else //1677-09-21_00-12-44 expected_string_os << 1677 << "-" << "09" @@ -171,7 +171,7 @@ TEST(time_utils_test, timestamp_to_string_to_timestamp) << "_" << "00" << "-" << "12" << "-" << "44"; - #endif // _EPROSIMA_WINDOWS_PLATFORM +#endif // _EPROSIMA_WINDOWS_PLATFORM // Test timestamp_to_string @@ -212,7 +212,7 @@ TEST(time_utils_test, timestamp_to_string_to_timestamp) std::string future_time_str = timestamp_to_string(future_time); std::ostringstream expected_string_os; - #if _EPROSIMA_WINDOWS_PLATFORM +#if _EPROSIMA_WINDOWS_PLATFORM && PLATFORM_32BIT expected_string_os << 2038 << "-" << "01" @@ -220,7 +220,7 @@ TEST(time_utils_test, timestamp_to_string_to_timestamp) << "_" << "03" << "-" << "14" << "-" << "07"; - #else +#else expected_string_os << 2049 << "-" << "05" @@ -228,7 +228,7 @@ TEST(time_utils_test, timestamp_to_string_to_timestamp) << "_" << "00" << "-" << "00" << "-" << "00"; - #endif // _EPROSIMA_WINDOWS_PLATFORM +#endif // _EPROSIMA_WINDOWS_PLATFORM // Test timestamp_to_string ASSERT_EQ(future_time_str, expected_string_os.str()); @@ -245,7 +245,7 @@ TEST(time_utils_test, timestamp_to_string_to_timestamp) std::string end_time_str = timestamp_to_string(end_time); std::ostringstream expected_string_os; - #if _EPROSIMA_WINDOWS_PLATFORM +#if _EPROSIMA_WINDOWS_PLATFORM && _PLATFORM_32BIT expected_string_os << 2038 << "-" << "01" @@ -253,7 +253,15 @@ TEST(time_utils_test, timestamp_to_string_to_timestamp) << "_" << "03" << "-" << "14" << "-" << "07"; - #else // 2262-04-11 23:47:16 +#elif _EPROSIMA_WINDOWS_PLATFORM && _PLATFORM_64BIT + expected_string_os + << 3000 + << "-" << "12" + << "-" << 31 + << "_" << "23" + << "-" << "59" + << "-" << "59"; +#else // 2262-04-11 23:47:16 expected_string_os << 2262 << "-" << "04" @@ -261,7 +269,7 @@ TEST(time_utils_test, timestamp_to_string_to_timestamp) << "_" << "23" << "-" << "47" << "-" << "16"; - #endif // _EPROSIMA_WINDOWS_PLATFORM +#endif // _EPROSIMA_WINDOWS_PLATFORM // Test timestamp_to_string From b8f3f7c62cd08162e828b81a1863793ac34f6886 Mon Sep 17 00:00:00 2001 From: Mario Dominguez Date: Wed, 2 Jul 2025 08:14:13 +0200 Subject: [PATCH 8/8] Refs #23440: Linter Signed-off-by: Mario Dominguez --- cpp_utils/include/cpp_utils/macros/macros.hpp | 5 +++-- cpp_utils/src/cpp/time/time_utils.cpp | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/cpp_utils/include/cpp_utils/macros/macros.hpp b/cpp_utils/include/cpp_utils/macros/macros.hpp index 69b6843d..f0d0e96c 100644 --- a/cpp_utils/include/cpp_utils/macros/macros.hpp +++ b/cpp_utils/include/cpp_utils/macros/macros.hpp @@ -87,11 +87,12 @@ namespace utils { #define _EPROSIMA_WINDOWS_PLATFORM 1 #endif // if defined(WIN32) || defined(_WIN32) || defined(__WIN32) || defined(WIN64) || defined(_WIN64) || defined(__WIN64) || defined(_MSC_VER) -#if defined(WIN64) || defined(_WIN64) || defined(__WIN64) || defined(_WIN64) || defined(__x86_64__) || defined(__ppc64__) || defined(__aarch64__) +#if defined(WIN64) || defined(_WIN64) || defined(__WIN64) || defined(_WIN64) || defined(__x86_64__) || \ + defined(__ppc64__) || defined(__aarch64__) #define _PLATFORM_64BIT 1 #else #define _PLATFORM_32BIT 1 -#endif +#endif // if defined(WIN64) || defined(_WIN64) || defined(__WIN64) || defined(_WIN64) || defined(__x86_64__) || defined(__ppc64__) || defined(__aarch64__) } /* namespace utils */ } /* namespace eprosima */ diff --git a/cpp_utils/src/cpp/time/time_utils.cpp b/cpp_utils/src/cpp/time/time_utils.cpp index bb68af16..77a5e026 100644 --- a/cpp_utils/src/cpp/time/time_utils.cpp +++ b/cpp_utils/src/cpp/time/time_utils.cpp @@ -155,7 +155,7 @@ Timestamp string_to_timestamp( if ((time_t)-1 == utc_time) { throw ValueNotAllowedException( - STR_ENTRY << "Failed to convert string to timestamp"); + STR_ENTRY << "Failed to convert string to timestamp"); } return Timeclock::from_time_t(utc_time);