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 
12 namespace redfish::time_utils
13 {
14 
15 std::optional<usSinceEpoch> dateStringToEpoch(std::string_view datetime)
16 {
17     for (const char* format : std::to_array({"%FT%T%Ez", "%FT%TZ", "%FT%T"}))
18     {
19         // Parse using signed so we can detect negative dates
20         std::chrono::sys_time<usSinceEpoch> date;
21         std::istringstream iss(std::string{datetime});
22 #if __cpp_lib_chrono >= 201907L
23         namespace chrono_from_stream = std::chrono;
24 #else
25         namespace chrono_from_stream = date;
26 #endif
27         if (chrono_from_stream::from_stream(iss, format, date))
28         {
29             if (date.time_since_epoch().count() < 0)
30             {
31                 return std::nullopt;
32             }
33             if (iss.rdbuf()->in_avail() != 0)
34             {
35                 // More information left at end of string.
36                 continue;
37             }
38             return date.time_since_epoch();
39         }
40     }
41     return std::nullopt;
42 }
43 } // namespace redfish::time_utils
44