1#include <userver/proto-structs/io/std/chrono/time_point.hpp>
3#include <google/protobuf/timestamp.pb.h>
4#include <google/protobuf/util/time_util.h>
6#include <userver/proto-structs/io/context.hpp>
7#include <userver/utils/assert.hpp>
9namespace proto_structs::io {
11std::chrono::time_point<std::chrono::system_clock> ReadProtoStruct(
13 To<std::chrono::time_point<std::chrono::system_clock>>,
14 const ::google::protobuf::Timestamp& msg
16 using TimePoint = std::chrono::time_point<std::chrono::system_clock>;
17 constexpr std::int64_t kMaxSecondsInTimePoint =
18 std::chrono::duration_cast<std::chrono::seconds>(TimePoint::duration::max()).count();
19 constexpr std::int64_t kMinSecondsInTimePoint =
20 std::chrono::duration_cast<std::chrono::seconds>(TimePoint::duration::min()).count();
24 if (::google::protobuf::util::TimeUtil::IsTimestampValid(msg)) {
25 if (msg.seconds() > kMaxSecondsInTimePoint - 1) {
26 result = TimePoint::max();
27 }
else if (msg.seconds() < kMinSecondsInTimePoint) {
28 result = TimePoint::min();
30 result = TimePoint{std::chrono::duration_cast<TimePoint::duration>(
31 std::chrono::seconds(msg.seconds()) + std::chrono::nanoseconds(msg.nanos())
35 ctx.AddError(
"invalid 'google.protobuf.Timestamp' value");
43 const std::chrono::time_point<std::chrono::system_clock>& obj,
44 ::google::protobuf::Timestamp& msg
46 using TimeUtil = ::google::protobuf::util::TimeUtil;
47 const auto seconds = std::chrono::duration_cast<std::chrono::seconds>(obj.time_since_epoch());
48 const std::chrono::nanoseconds nanos = obj.time_since_epoch() - seconds;
50 if (seconds.count() > TimeUtil::kTimestampMaxSeconds) {
51 msg.set_seconds(TimeUtil::kTimestampMaxSeconds);
53 }
else if (seconds.count() < TimeUtil::kTimestampMinSeconds) {
54 msg.set_seconds(TimeUtil::kTimestampMinSeconds);
56 }
else if (nanos.count() >= 0) {
57 msg.set_seconds(seconds.count());
58 msg.set_nanos(nanos.count());
61 msg.set_seconds(seconds.count() - 1);
62 msg.set_nanos(nanos.count() + 1'000'000'000);
65 UASSERT(TimeUtil::IsTimestampValid(msg));