11b8b02a4SEd Tanous #include "utils/time_utils.hpp" 21b8b02a4SEd Tanous 3*67b2e53bSEd Tanous #include <version> 4*67b2e53bSEd Tanous 5a8770740SEd Tanous #if __cpp_lib_chrono < 201907L 61b8b02a4SEd Tanous #include "utils/extern/date.h" 7a8770740SEd Tanous #endif 81b8b02a4SEd Tanous 91b8b02a4SEd Tanous #include <array> 101b8b02a4SEd Tanous #include <chrono> 111b8b02a4SEd Tanous #include <optional> 121b8b02a4SEd Tanous #include <sstream> 131b8b02a4SEd Tanous #include <string> 141b8b02a4SEd Tanous #include <string_view> 151b8b02a4SEd Tanous 161b8b02a4SEd Tanous namespace redfish::time_utils 171b8b02a4SEd Tanous { 18c51afd54SEd Tanous 191b8b02a4SEd Tanous std::optional<usSinceEpoch> dateStringToEpoch(std::string_view datetime) 201b8b02a4SEd Tanous { 21352e3b78SHieu Huynh for (const char* format : std::to_array( 22352e3b78SHieu Huynh {"%FT%T%Ez", "%FT%TZ", "%FT%T", "%Y%m%d", "%Y%m%dT%H%M%SZ"})) 231b8b02a4SEd Tanous { 241b8b02a4SEd Tanous // Parse using signed so we can detect negative dates 25c51afd54SEd Tanous std::chrono::sys_time<usSinceEpoch> date; 261b8b02a4SEd Tanous std::istringstream iss(std::string{datetime}); 271b8b02a4SEd Tanous #if __cpp_lib_chrono >= 201907L 281b8b02a4SEd Tanous namespace chrono_from_stream = std::chrono; 291b8b02a4SEd Tanous #else 301b8b02a4SEd Tanous namespace chrono_from_stream = date; 311b8b02a4SEd Tanous #endif 321b8b02a4SEd Tanous if (chrono_from_stream::from_stream(iss, format, date)) 331b8b02a4SEd Tanous { 341b8b02a4SEd Tanous if (date.time_since_epoch().count() < 0) 351b8b02a4SEd Tanous { 361b8b02a4SEd Tanous return std::nullopt; 371b8b02a4SEd Tanous } 381b8b02a4SEd Tanous if (iss.rdbuf()->in_avail() != 0) 391b8b02a4SEd Tanous { 401b8b02a4SEd Tanous // More information left at end of string. 411b8b02a4SEd Tanous continue; 421b8b02a4SEd Tanous } 43c51afd54SEd Tanous return date.time_since_epoch(); 441b8b02a4SEd Tanous } 451b8b02a4SEd Tanous } 461b8b02a4SEd Tanous return std::nullopt; 471b8b02a4SEd Tanous } 481b8b02a4SEd Tanous } // namespace redfish::time_utils 49