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