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
7273Timestamp 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