10#include <google/protobuf/duration.pb.h>
11#include <google/protobuf/timestamp.pb.h>
12#include <google/type/date.pb.h>
14#include <userver/formats/json_fwd.hpp>
15#include <userver/formats/parse/to.hpp>
16#include <userver/formats/serialize/to.hpp>
17#include <userver/utils/assert.hpp>
18#include <userver/utils/datetime/cpp_20_calendar.hpp>
19#include <userver/utils/datetime/date.hpp>
21USERVER_NAMESPACE_BEGIN
29bool IsValid(
const google::protobuf::Timestamp& grpc_ts);
34 using std::overflow_error::overflow_error;
40template <
class Duration>
41google::protobuf::Timestamp
ToProtoTimestamp(
const std::chrono::time_point<std::chrono::system_clock, Duration>&
43 const auto seconds = std::chrono::duration_cast<std::chrono::seconds>(system_tp.time_since_epoch());
44 const auto nanos = std::chrono::duration_cast<std::chrono::nanoseconds>(system_tp.time_since_epoch() - seconds);
46 google::protobuf::Timestamp timestamp;
47 timestamp.set_seconds(seconds.count());
48 timestamp.set_nanos(nanos.count());
59template <
class Duration = std::chrono::system_clock::duration>
60std::chrono::time_point<std::chrono::system_clock, Duration>
ToTimePoint(
const google::protobuf::Timestamp& grpc_ts) {
65 const std::chrono::seconds seconds(grpc_ts.seconds());
68 if (seconds >= std::chrono::duration_cast<std::chrono::seconds>(Duration::max())) {
72 return std::chrono::time_point<
73 std::chrono::system_clock,
74 Duration>(std::chrono::duration_cast<
75 Duration>(seconds + std::chrono::duration_cast<Duration>(std::chrono::nanoseconds(grpc_ts.nanos()))));
86bool IsValid(
const google::type::Date& grpc_date);
91 using std::overflow_error::overflow_error;
94#if __cpp_lib_chrono >= 201907L
99google::type::Date ToProtoDate(
const std::chrono::year_month_day& system_date);
104std::chrono::year_month_day ToYearMonthDay(
const google::type::Date& grpc_date);
111google::type::Date
ToProtoDate(
const utils::datetime::Date& utils_date);
116utils::datetime::Date
ToUtilsDate(
const google::type::Date& grpc_date);
121template <
class Duration>
122google::type::Date
ToProtoDate(
const std::chrono::time_point<std::chrono::system_clock, Duration>& system_tp) {
123 return ToProtoDate(utils::datetime::Date(std::chrono::floor<utils::datetime::Date::Days>(system_tp))
);
129std::chrono::time_point<std::chrono::system_clock, utils::datetime::Days>
ToTimePoint(
130 const google::type::Date& grpc_date
142bool IsValid(
const google::protobuf::Duration& grpc_duration);
147 using std::overflow_error::overflow_error;
153template <
class Duration = std::chrono::microseconds>
154Duration
ToDuration(
const google::protobuf::Duration& grpc_duration) {
159 const std::chrono::seconds seconds(grpc_duration.seconds());
162 if (seconds >= std::chrono::duration_cast<std::chrono::seconds>(Duration::max())) {
165 return std::chrono::duration_cast<
166 Duration>(seconds + std::chrono::duration_cast<Duration>(std::chrono::nanoseconds(grpc_duration.nanos())));
172template <
class Rep,
class Period>
173google::protobuf::Duration
ToProtoDuration(
const std::chrono::duration<Rep, Period>& duration) {
174 const auto seconds = std::chrono::duration_cast<std::chrono::seconds>(duration);
175 const auto nanos = std::chrono::duration_cast<std::chrono::nanoseconds>(duration - seconds);
177 google::protobuf::Duration result;
178 result.set_seconds(seconds.count());
179 result.set_nanos(nanos.count());
188namespace formats::parse {
190google::protobuf::Timestamp Parse(
const formats::json::Value& json, formats::parse::To<google::protobuf::Timestamp>);
192google::type::Date Parse(
const formats::json::Value& json, formats::parse::To<google::type::Date>);
196namespace formats::serialize {
198formats::json::Value Serialize(
const google::protobuf::Timestamp& value, formats::serialize::To<formats::json::Value>);
200formats::json::Value Serialize(
const google::type::Date& value, formats::serialize::To<formats::json::Value>);