1 #include "utils/time_utils.hpp" 2 3 #include "utils/extern/date.h" 4 5 #include <array> 6 #include <chrono> 7 #include <optional> 8 #include <sstream> 9 #include <string> 10 #include <string_view> 11 #include <version> 12 13 namespace redfish::time_utils 14 { 15 using usSinceEpoch = std::chrono::duration<uint64_t, std::micro>; 16 std::optional<usSinceEpoch> dateStringToEpoch(std::string_view datetime) 17 { 18 for (const char* format : std::to_array({"%FT%T%Ez", "%FT%TZ", "%FT%T"})) 19 { 20 // Parse using signed so we can detect negative dates 21 std::chrono::sys_time<std::chrono::duration<int64_t, std::micro>> date; 22 std::istringstream iss(std::string{datetime}); 23 #if __cpp_lib_chrono >= 201907L 24 namespace chrono_from_stream = std::chrono; 25 #else 26 namespace chrono_from_stream = date; 27 #endif 28 if (chrono_from_stream::from_stream(iss, format, date)) 29 { 30 if (date.time_since_epoch().count() < 0) 31 { 32 return std::nullopt; 33 } 34 if (iss.rdbuf()->in_avail() != 0) 35 { 36 // More information left at end of string. 37 continue; 38 } 39 return usSinceEpoch{date.time_since_epoch().count()}; 40 } 41 } 42 return std::nullopt; 43 } 44 } // namespace redfish::time_utils 45