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