xref: /openbmc/bmcweb/features/redfish/src/utils/time_utils.cpp (revision 40e9b92ec19acffb46f83a6e55b18974da5d708e)
1*40e9b92eSEd Tanous // SPDX-License-Identifier: Apache-2.0
2*40e9b92eSEd Tanous // SPDX-FileCopyrightText: Copyright OpenBMC Authors
31b8b02a4SEd Tanous #include "utils/time_utils.hpp"
41b8b02a4SEd Tanous 
567b2e53bSEd Tanous #include <version>
667b2e53bSEd Tanous 
7a8770740SEd Tanous #if __cpp_lib_chrono < 201907L
81b8b02a4SEd Tanous #include "utils/extern/date.h"
9a8770740SEd Tanous #endif
101b8b02a4SEd Tanous 
111b8b02a4SEd Tanous #include <array>
121b8b02a4SEd Tanous #include <chrono>
131b8b02a4SEd Tanous #include <optional>
141b8b02a4SEd Tanous #include <sstream>
151b8b02a4SEd Tanous #include <string>
161b8b02a4SEd Tanous #include <string_view>
171b8b02a4SEd Tanous 
181b8b02a4SEd Tanous namespace redfish::time_utils
191b8b02a4SEd Tanous {
20c51afd54SEd Tanous 
211b8b02a4SEd Tanous std::optional<usSinceEpoch> dateStringToEpoch(std::string_view datetime)
221b8b02a4SEd Tanous {
23352e3b78SHieu Huynh     for (const char* format : std::to_array(
24352e3b78SHieu Huynh              {"%FT%T%Ez", "%FT%TZ", "%FT%T", "%Y%m%d", "%Y%m%dT%H%M%SZ"}))
251b8b02a4SEd Tanous     {
261b8b02a4SEd Tanous         // Parse using signed so we can detect negative dates
27c51afd54SEd Tanous         std::chrono::sys_time<usSinceEpoch> date;
281b8b02a4SEd Tanous         std::istringstream iss(std::string{datetime});
291b8b02a4SEd Tanous #if __cpp_lib_chrono >= 201907L
301b8b02a4SEd Tanous         namespace chrono_from_stream = std::chrono;
311b8b02a4SEd Tanous #else
321b8b02a4SEd Tanous         namespace chrono_from_stream = date;
331b8b02a4SEd Tanous #endif
341b8b02a4SEd Tanous         if (chrono_from_stream::from_stream(iss, format, date))
351b8b02a4SEd Tanous         {
361b8b02a4SEd Tanous             if (date.time_since_epoch().count() < 0)
371b8b02a4SEd Tanous             {
381b8b02a4SEd Tanous                 return std::nullopt;
391b8b02a4SEd Tanous             }
401b8b02a4SEd Tanous             if (iss.rdbuf()->in_avail() != 0)
411b8b02a4SEd Tanous             {
421b8b02a4SEd Tanous                 // More information left at end of string.
431b8b02a4SEd Tanous                 continue;
441b8b02a4SEd Tanous             }
45c51afd54SEd Tanous             return date.time_since_epoch();
461b8b02a4SEd Tanous         }
471b8b02a4SEd Tanous     }
481b8b02a4SEd Tanous     return std::nullopt;
491b8b02a4SEd Tanous }
501b8b02a4SEd Tanous } // namespace redfish::time_utils
51