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>
23FromStringSaturating(const std::string& timestring, const std::string& format) {
24 using TimePoint = std::chrono::time_point<std::chrono::system_clock, Duration>;
25
26 constexpr cctz::time_point<Days> kTaxiInfinity{DaysBetweenYears(1970, 10000)};
27
28 // reimplement cctz::parse() because we cannot distinguish overflow otherwise
29 cctz::time_point<cctz::seconds> tp_seconds;
30 cctz::detail::femtoseconds femtoseconds;
31 if (!cctz::detail::parse(format, timestring, cctz::utc_time_zone(), &tp_seconds, &femtoseconds)) {
32 throw DateParseError(timestring);
33 }
34
35 // manually cast to a coarser time_point
36 if (std::chrono::time_point_cast<Days>(tp_seconds) >= kTaxiInfinity ||
37 tp_seconds > std::chrono::time_point_cast<decltype(tp_seconds)::duration>(TimePoint::max())) {
38 return TimePoint::max();
39 }
40
41 return std::chrono::time_point_cast<Duration>(tp_seconds) + std::chrono::duration_cast<Duration>(femtoseconds);
42}
43
44/// @brief Converts strings like "2012-12-12T00:00:00" to
45/// std::chrono::system_clock::time_point in UTC timezone and saturates on overflow
46/// Example:
47/// @snippet utils/datetime/from_string_saturating_test.cpp FromStringSaturation
48template <class Duration = std::chrono::system_clock::duration>
49std::chrono::time_point<std::chrono::system_clock, Duration> FromRfc3339StringSaturating(const std::string& timestring
50) {
51 return FromStringSaturating<Duration>(timestring, kRfc3339Format);
52}
53
54} // namespace utils::datetime
55
56USERVER_NAMESPACE_END