userver: userver/utils/datetime/from_string_saturating.hpp Source File
Loading...
Searching...
No Matches
from_string_saturating.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/utils/datetime/from_string_saturating.hpp
4/// @brief Saturating converters from strings to time points.
5/// @ingroup userver_universal
6
7#include <chrono>
8#include <string>
9
10#include <cctz/time_zone.h>
11
12#include <userver/utils/datetime/cpp_20_calendar.hpp>
13#include <userver/utils/datetime_light.hpp>
14
15USERVER_NAMESPACE_BEGIN
16
17namespace utils::datetime {
18
19/// @brief Converts strings of the specified format starting with "%Y" to
20/// std::chrono::system_clock::time_point in UTC timezone and saturates on overflow.
21template <class Duration = std::chrono::system_clock::duration>
22std::chrono::time_point<std::chrono::system_clock, Duration> FromStringSaturating(
23 const std::string& timestring,
24 const std::string& format
25) {
26 using TimePoint = std::chrono::time_point<std::chrono::system_clock, Duration>;
27
28 constexpr cctz::time_point<Days> kTaxiInfinity{DaysBetweenYears(1970, 10000)};
29
30 // reimplement cctz::parse() because we cannot distinguish overflow otherwise
31 cctz::time_point<cctz::seconds> tp_seconds;
32 cctz::detail::femtoseconds femtoseconds;
33 if (!cctz::detail::parse(format, timestring, cctz::utc_time_zone(), &tp_seconds, &femtoseconds)) {
34 throw DateParseError(timestring);
35 }
36
37 // manually cast to a coarser time_point
38 if (std::chrono::time_point_cast<Days>(tp_seconds) >= kTaxiInfinity ||
39 tp_seconds > std::chrono::time_point_cast<decltype(tp_seconds)::duration>(TimePoint::max()))
40 {
41 return TimePoint::max();
42 }
43
44 return std::chrono::time_point_cast<Duration>(tp_seconds) + std::chrono::duration_cast<Duration>(femtoseconds);
45}
46
47/// @brief Converts strings like "2012-12-12T00:00:00" to
48/// std::chrono::system_clock::time_point in UTC timezone and saturates on overflow
49/// Example:
50/// @snippet utils/datetime/from_string_saturating_test.cpp FromStringSaturation
51template <class Duration = std::chrono::system_clock::duration>
52std::chrono::time_point<std::chrono::system_clock, Duration> FromRfc3339StringSaturating(const std::string& timestring
53) {
54 return FromStringSaturating<Duration>(timestring, kRfc3339Format);
55}
56
57} // namespace utils::datetime
58
59USERVER_NAMESPACE_END