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