Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 36 additions & 38 deletions src/google/protobuf/util/time_util.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

#include <cstdint>
#include <cstdlib>
#include <ctime>
#include <string>

#include "google/protobuf/duration.pb.h"
#include "google/protobuf/timestamp.pb.h"
Expand Down Expand Up @@ -41,11 +43,7 @@ static constexpr int32_t kSecondsPerMinute =
60; // Note that we ignore leap seconds.
static constexpr int32_t kSecondsPerHour = 3600;

template <typename T>
T CreateNormalized(int64_t seconds, int32_t nanos);

template <>
Timestamp CreateNormalized(int64_t seconds, int32_t nanos) {
Timestamp CreateNormalizedTimestamp(int64_t seconds, int32_t nanos) {
ABSL_DCHECK(seconds >= TimeUtil::kTimestampMinSeconds &&
seconds <= TimeUtil::kTimestampMaxSeconds)
<< "Timestamp seconds are outside of the valid range";
Expand All @@ -68,12 +66,11 @@ Timestamp CreateNormalized(int64_t seconds, int32_t nanos) {
<< "Timestamp is outside of the valid range";
Timestamp result;
result.set_seconds(seconds);
result.set_nanos(static_cast<int32_t>(nanos));
result.set_nanos(nanos);
return result;
}

template <>
Duration CreateNormalized(int64_t seconds, int32_t nanos) {
Duration CreateNormalizedDuration(int64_t seconds, int32_t nanos) {
ABSL_DCHECK(seconds >= TimeUtil::kDurationMinSeconds &&
seconds <= TimeUtil::kDurationMaxSeconds)
<< "Duration seconds are outside of the valid range";
Expand All @@ -99,7 +96,7 @@ Duration CreateNormalized(int64_t seconds, int32_t nanos) {
<< "Duration is outside of the valid range";
Duration result;
result.set_seconds(seconds);
result.set_nanos(static_cast<int32_t>(nanos));
result.set_nanos(nanos);
return result;
}

Expand Down Expand Up @@ -192,15 +189,15 @@ bool TimeUtil::FromString(absl::string_view value, Timestamp* timestamp) {
if (!ParseTime(value, &seconds, &nanos)) {
return false;
}
*timestamp = CreateNormalized<Timestamp>(seconds, nanos);
*timestamp = CreateNormalizedTimestamp(seconds, nanos);
return true;
}

Timestamp TimeUtil::GetCurrentTime() {
int64_t seconds;
int32_t nanos;
CurrentTime(&seconds, &nanos);
return CreateNormalized<Timestamp>(seconds, nanos);
return CreateNormalizedTimestamp(seconds, nanos);
}

Timestamp TimeUtil::GetEpoch() { return Timestamp(); }
Expand Down Expand Up @@ -271,24 +268,24 @@ bool TimeUtil::FromString(absl::string_view value, Duration* duration) {
}

Duration TimeUtil::NanosecondsToDuration(int64_t nanos) {
return CreateNormalized<Duration>(nanos / kNanosPerSecond,
nanos % kNanosPerSecond);
return CreateNormalizedDuration(nanos / kNanosPerSecond,
nanos % kNanosPerSecond);
}

Duration TimeUtil::MicrosecondsToDuration(int64_t micros) {
return CreateNormalized<Duration>(
return CreateNormalizedDuration(
micros / kMicrosPerSecond,
(micros % kMicrosPerSecond) * kNanosPerMicrosecond);
}

Duration TimeUtil::MillisecondsToDuration(int64_t millis) {
return CreateNormalized<Duration>(
return CreateNormalizedDuration(
millis / kMillisPerSecond,
(millis % kMillisPerSecond) * kNanosPerMillisecond);
}

Duration TimeUtil::SecondsToDuration(int64_t seconds) {
return CreateNormalized<Duration>(seconds, 0);
return CreateNormalizedDuration(seconds, 0);
}

Duration TimeUtil::MinutesToDuration(int64_t minutes) {
Expand Down Expand Up @@ -336,24 +333,24 @@ int64_t TimeUtil::DurationToHours(const Duration& duration) {
}

Timestamp TimeUtil::NanosecondsToTimestamp(int64_t nanos) {
return CreateNormalized<Timestamp>(nanos / kNanosPerSecond,
nanos % kNanosPerSecond);
return CreateNormalizedTimestamp(nanos / kNanosPerSecond,
nanos % kNanosPerSecond);
}

Timestamp TimeUtil::MicrosecondsToTimestamp(int64_t micros) {
return CreateNormalized<Timestamp>(
return CreateNormalizedTimestamp(
micros / kMicrosPerSecond,
micros % kMicrosPerSecond * kNanosPerMicrosecond);
}

Timestamp TimeUtil::MillisecondsToTimestamp(int64_t millis) {
return CreateNormalized<Timestamp>(
return CreateNormalizedTimestamp(
millis / kMillisPerSecond,
millis % kMillisPerSecond * kNanosPerMillisecond);
}

Timestamp TimeUtil::SecondsToTimestamp(int64_t seconds) {
return CreateNormalized<Timestamp>(seconds, 0);
return CreateNormalizedTimestamp(seconds, 0);
}

int64_t TimeUtil::TimestampToNanoseconds(const Timestamp& timestamp) {
Expand Down Expand Up @@ -383,16 +380,16 @@ int64_t TimeUtil::TimestampToSeconds(const Timestamp& timestamp) {
}

Timestamp TimeUtil::TimeTToTimestamp(time_t value) {
return CreateNormalized<Timestamp>(static_cast<int64_t>(value), 0);
return CreateNormalizedTimestamp(static_cast<int64_t>(value), 0);
}

time_t TimeUtil::TimestampToTimeT(const Timestamp& value) {
return static_cast<time_t>(value.seconds());
}

Timestamp TimeUtil::TimevalToTimestamp(const struct timeval& value) {
return CreateNormalized<Timestamp>(value.tv_sec,
value.tv_usec * kNanosPerMicrosecond);
return CreateNormalizedTimestamp(value.tv_sec,
value.tv_usec * kNanosPerMicrosecond);
}

struct timeval TimeUtil::TimestampToTimeval(const Timestamp& value) {
Expand All @@ -403,8 +400,8 @@ struct timeval TimeUtil::TimestampToTimeval(const Timestamp& value) {
}

Duration TimeUtil::TimevalToDuration(const struct timeval& value) {
return CreateNormalized<Duration>(value.tv_sec,
value.tv_usec * kNanosPerMicrosecond);
return CreateNormalizedDuration(value.tv_sec,
value.tv_usec * kNanosPerMicrosecond);
}

struct timeval TimeUtil::DurationToTimeval(const Duration& value) {
Expand All @@ -426,7 +423,8 @@ struct timeval TimeUtil::DurationToTimeval(const Duration& value) {
namespace google {
namespace protobuf {
namespace {
using ::google::protobuf::util::CreateNormalized;
using ::google::protobuf::util::CreateNormalizedDuration;
using ::google::protobuf::util::CreateNormalizedTimestamp;
using ::google::protobuf::util::kNanosPerSecond;

// Convert a Duration to uint128.
Expand Down Expand Up @@ -457,14 +455,14 @@ void ToDuration(const absl::uint128 value, bool negative, Duration* duration) {
} // namespace

Duration& operator+=(Duration& d1, const Duration& d2) {
d1 = CreateNormalized<Duration>(d1.seconds() + d2.seconds(),
d1.nanos() + d2.nanos());
d1 = CreateNormalizedDuration(d1.seconds() + d2.seconds(),
d1.nanos() + d2.nanos());
return d1;
}

Duration& operator-=(Duration& d1, const Duration& d2) { // NOLINT
d1 = CreateNormalized<Duration>(d1.seconds() - d2.seconds(),
d1.nanos() - d2.nanos());
d1 = CreateNormalizedDuration(d1.seconds() - d2.seconds(),
d1.nanos() - d2.nanos());
return d1;
}

Expand Down Expand Up @@ -493,7 +491,7 @@ Duration& operator*=(Duration& d, double r) { // NOLINT
// sign from seconds but also that nanos can be any arbitrary value when
// overflow happens (i.e., the result is a much larger value than what
// int64 can represent).
d = CreateNormalized<Duration>(seconds, nanos);
d = CreateNormalizedDuration(seconds, nanos);
return d;
}

Expand Down Expand Up @@ -544,20 +542,20 @@ int64_t operator/(const Duration& d1, const Duration& d2) {
}

Timestamp& operator+=(Timestamp& t, const Duration& d) { // NOLINT
t = CreateNormalized<Timestamp>(t.seconds() + d.seconds(),
t.nanos() + d.nanos());
t = CreateNormalizedTimestamp(t.seconds() + d.seconds(),
t.nanos() + d.nanos());
return t;
}

Timestamp& operator-=(Timestamp& t, const Duration& d) { // NOLINT
t = CreateNormalized<Timestamp>(t.seconds() - d.seconds(),
t.nanos() - d.nanos());
t = CreateNormalizedTimestamp(t.seconds() - d.seconds(),
t.nanos() - d.nanos());
return t;
}

Duration operator-(const Timestamp& t1, const Timestamp& t2) {
return CreateNormalized<Duration>(t1.seconds() - t2.seconds(),
t1.nanos() - t2.nanos());
return CreateNormalizedDuration(t1.seconds() - t2.seconds(),
t1.nanos() - t2.nanos());
}
} // namespace protobuf
} // namespace google
Expand Down
1 change: 1 addition & 0 deletions src/google/protobuf/util/time_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

#include "google/protobuf/duration.pb.h"
#include "google/protobuf/timestamp.pb.h"
#include "absl/strings/string_view.h"

// Must be included last.
#include "google/protobuf/port_def.inc"
Expand Down
Loading