Skip to content

Commit 72a043d

Browse files
committed
Refs #23440: normalize(time_t) method
Signed-off-by: Mario Dominguez <mariodominguez@eprosima.com>
1 parent fd2bc65 commit 72a043d

2 files changed

Lines changed: 47 additions & 16 deletions

File tree

cpp_utils/include/cpp_utils/time/time_utils.hpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,5 +103,17 @@ CPP_UTILS_DllAPI std::chrono::milliseconds duration_to_ms(
103103
CPP_UTILS_DllAPI void sleep_for(
104104
const Duration_ms& sleep_time) noexcept;
105105

106+
/**
107+
* @brief Makes sure that the time is clamped into a valid range.
108+
* This is useful for keeping time values within the ranges
109+
* depending on the platform.
110+
*
111+
* @param time time to normalize.
112+
*
113+
* @return normalized time value.
114+
*/
115+
CPP_UTILS_DllAPI time_t normalize(
116+
const time_t& time) noexcept;
117+
106118
} /* namespace utils */
107119
} /* namespace eprosima */

cpp_utils/src/cpp/time/time_utils.cpp

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include <cpp_utils/macros/macros.hpp>
2525
#include <cpp_utils/time/time_utils.hpp>
2626
#include <cpp_utils/exception/PreconditionNotMet.hpp>
27+
#include <cpp_utils/exception/ValueNotAllowedException.hpp>
2728
#include <cpp_utils/Log.hpp>
2829

2930
// These functions has different names in windows
@@ -66,7 +67,7 @@ Timestamp date_to_timestamp(
6667
tm.tm_mon = static_cast<int>(month) - 1;
6768
tm.tm_year = static_cast<int>(year) - 1900;
6869

69-
return Timeclock::from_time_t(timegm(&tm));
70+
return Timeclock::from_time_t(normalize(timegm(&tm)));
7071
}
7172

7273
Timestamp time_to_timestamp(
@@ -77,9 +78,7 @@ Timestamp time_to_timestamp(
7778
std::tm tm;
7879

7980
// Initialise with current timestamp to set date
80-
auto current_ts = now();
81-
std::chrono::high_resolution_clock::time_point::duration duration = current_ts.time_since_epoch();
82-
time_t duration_seconds = std::chrono::duration_cast<std::chrono::seconds>(duration).count();
81+
time_t duration_seconds = normalize(Timeclock::to_time_t(now()));
8382
tm = *std::gmtime(&duration_seconds);
8483

8584
tm.tm_sec = static_cast<int>(second);
@@ -95,18 +94,7 @@ std::string timestamp_to_string(
9594
bool local_time /* = false */)
9695
{
9796
std::ostringstream ss;
98-
time_t duration_seconds = std::chrono::duration_cast<std::chrono::seconds>(timestamp.time_since_epoch()).count();
99-
100-
#if _EPROSIMA_WINDOWS_PLATFORM // In Windows std::gmtime does not support negative values nor values greater than 2^32
101-
time_t max_value = std::numeric_limits<int32_t>::max();
102-
if (0 > duration_seconds || duration_seconds > max_value)
103-
{
104-
EPROSIMA_LOG_WARNING(TIME_UTILS,
105-
"Timestamp value: " << duration_seconds << " is out of range for Windows, clamping to 0 and " <<
106-
max_value);
107-
duration_seconds = std::max((time_t) 0, std::min(max_value, duration_seconds));
108-
}
109-
#endif // if _EPROSIMA_WINDOWS_PLATFORM
97+
time_t duration_seconds = normalize(Timeclock::to_time_t(timestamp));
11098

11199
std::tm* tm = nullptr;
112100
if (local_time)
@@ -163,6 +151,13 @@ Timestamp string_to_timestamp(
163151
{
164152
utc_time = timegm(&tm);
165153
}
154+
155+
if ((time_t)-1 == utc_time)
156+
{
157+
throw ValueNotAllowedException(
158+
STR_ENTRY << "Failed to convert string to timestamp");
159+
}
160+
166161
return Timeclock::from_time_t(utc_time);
167162
}
168163

@@ -178,5 +173,29 @@ void sleep_for(
178173
std::this_thread::sleep_for(duration_to_ms(sleep_time));
179174
}
180175

176+
time_t normalize(
177+
const time_t& time) noexcept
178+
{
179+
time_t normalized_time = time;
180+
#if _EPROSIMA_WINDOWS_PLATFORM // In Windows std::gmtime does not support negative values
181+
time_t max_value;
182+
183+
#if _PLATFORM_64BIT
184+
max_value = 32535215999; // In WIN64, max value is 3000-12-31_23-59-59
185+
#else
186+
max_value = std::numeric_limits<int32_t>::max(); // In WIN32, values greater than 2^32 are not supported
187+
#endif // if PLATFORM_64BIT
188+
189+
if (0 > time || time > max_value)
190+
{
191+
EPROSIMA_LOG_WARNING(TIME_UTILS,
192+
"Timestamp value: " << time << " is out of range for Windows, clamping to 0 and " <<
193+
max_value);
194+
normalized_time = std::max((time_t) 0, std::min(max_value, time));
195+
}
196+
#endif // if _EPROSIMA_WINDOWS_PLATFORM
197+
return normalized_time;
198+
}
199+
181200
} /* namespace utils */
182201
} /* namespace eprosima */

0 commit comments

Comments
 (0)