diff --git a/BUILD b/BUILD
index 1f15e853dbc..c36c371f8c3 100644
--- a/BUILD
+++ b/BUILD
@@ -566,6 +566,7 @@ grpc_cc_library(
"src/core/lib/gprpp/stat_windows.cc",
"src/core/lib/gprpp/thd_posix.cc",
"src/core/lib/gprpp/thd_windows.cc",
+ "src/core/lib/gprpp/time_util.cc",
"src/core/lib/profiling/basic_timers.cc",
"src/core/lib/profiling/stap_timers.cc",
],
@@ -600,6 +601,7 @@ grpc_cc_library(
"src/core/lib/gprpp/stat.h",
"src/core/lib/gprpp/sync.h",
"src/core/lib/gprpp/thd.h",
+ "src/core/lib/gprpp/time_util.h",
"src/core/lib/profiling/timers.h",
],
external_deps = [
diff --git a/BUILD.gn b/BUILD.gn
index e4bdeffc241..eb38bc542e0 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -169,6 +169,8 @@ config("grpc_config") {
"src/core/lib/gprpp/thd.h",
"src/core/lib/gprpp/thd_posix.cc",
"src/core/lib/gprpp/thd_windows.cc",
+ "src/core/lib/gprpp/time_util.cc",
+ "src/core/lib/gprpp/time_util.h",
"src/core/lib/profiling/basic_timers.cc",
"src/core/lib/profiling/stap_timers.cc",
"src/core/lib/profiling/timers.h",
diff --git a/CMakeLists.txt b/CMakeLists.txt
index cb35d9b2a0a..8f65b541298 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -937,6 +937,7 @@ if(gRPC_BUILD_TESTS)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_cxx time_jump_test)
endif()
+ add_dependencies(buildtests_cxx time_util_test)
add_dependencies(buildtests_cxx timer_test)
add_dependencies(buildtests_cxx tls_security_connector_test)
add_dependencies(buildtests_cxx too_many_pings_test)
@@ -1338,6 +1339,7 @@ add_library(gpr
src/core/lib/gprpp/stat_windows.cc
src/core/lib/gprpp/thd_posix.cc
src/core/lib/gprpp/thd_windows.cc
+ src/core/lib/gprpp/time_util.cc
src/core/lib/profiling/basic_timers.cc
src/core/lib/profiling/stap_timers.cc
)
@@ -15043,6 +15045,44 @@ endif()
endif()
if(gRPC_BUILD_TESTS)
+add_executable(time_util_test
+ test/core/gprpp/time_util_test.cc
+ third_party/googletest/googletest/src/gtest-all.cc
+ third_party/googletest/googlemock/src/gmock-all.cc
+)
+
+target_include_directories(time_util_test
+ PRIVATE
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/include
+ ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}
+ ${_gRPC_RE2_INCLUDE_DIR}
+ ${_gRPC_SSL_INCLUDE_DIR}
+ ${_gRPC_UPB_GENERATED_DIR}
+ ${_gRPC_UPB_GRPC_GENERATED_DIR}
+ ${_gRPC_UPB_INCLUDE_DIR}
+ ${_gRPC_ZLIB_INCLUDE_DIR}
+ third_party/googletest/googletest/include
+ third_party/googletest/googletest
+ third_party/googletest/googlemock/include
+ third_party/googletest/googlemock
+ ${_gRPC_PROTO_GENS_DIR}
+)
+
+target_link_libraries(time_util_test
+ ${_gRPC_PROTOBUF_LIBRARIES}
+ ${_gRPC_ALLTARGETS_LIBRARIES}
+ grpc_test_util
+ grpc
+ gpr
+ address_sorting
+ upb
+)
+
+
+endif()
+if(gRPC_BUILD_TESTS)
+
add_executable(timer_test
test/cpp/common/timer_test.cc
third_party/googletest/googletest/src/gtest-all.cc
diff --git a/Makefile b/Makefile
index 71c076bfc5d..9fed6748ef9 100644
--- a/Makefile
+++ b/Makefile
@@ -947,6 +947,7 @@ LIBGPR_SRC = \
src/core/lib/gprpp/stat_windows.cc \
src/core/lib/gprpp/thd_posix.cc \
src/core/lib/gprpp/thd_windows.cc \
+ src/core/lib/gprpp/time_util.cc \
src/core/lib/profiling/basic_timers.cc \
src/core/lib/profiling/stap_timers.cc \
diff --git a/build_autogenerated.yaml b/build_autogenerated.yaml
index f6444d1b7be..4873cfe4814 100644
--- a/build_autogenerated.yaml
+++ b/build_autogenerated.yaml
@@ -308,6 +308,7 @@ libs:
- src/core/lib/gprpp/stat.h
- src/core/lib/gprpp/sync.h
- src/core/lib/gprpp/thd.h
+ - src/core/lib/gprpp/time_util.h
- src/core/lib/profiling/timers.h
src:
- src/core/lib/gpr/alloc.cc
@@ -352,6 +353,7 @@ libs:
- src/core/lib/gprpp/stat_windows.cc
- src/core/lib/gprpp/thd_posix.cc
- src/core/lib/gprpp/thd_windows.cc
+ - src/core/lib/gprpp/time_util.cc
- src/core/lib/profiling/basic_timers.cc
- src/core/lib/profiling/stap_timers.cc
deps:
@@ -7719,6 +7721,20 @@ targets:
- linux
- posix
- mac
+- name: time_util_test
+ gtest: true
+ build: test
+ language: c++
+ headers: []
+ src:
+ - test/core/gprpp/time_util_test.cc
+ deps:
+ - grpc_test_util
+ - grpc
+ - gpr
+ - address_sorting
+ - upb
+ uses_polling: false
- name: timer_test
gtest: true
build: test
diff --git a/config.m4 b/config.m4
index 8afbec900c2..e9f24adaeba 100644
--- a/config.m4
+++ b/config.m4
@@ -384,6 +384,7 @@ if test "$PHP_GRPC" != "no"; then
src/core/lib/gprpp/stat_windows.cc \
src/core/lib/gprpp/thd_posix.cc \
src/core/lib/gprpp/thd_windows.cc \
+ src/core/lib/gprpp/time_util.cc \
src/core/lib/http/format_request.cc \
src/core/lib/http/httpcli.cc \
src/core/lib/http/httpcli_security_connector.cc \
diff --git a/config.w32 b/config.w32
index f004ec6d393..cddbd9ffdfc 100644
--- a/config.w32
+++ b/config.w32
@@ -351,6 +351,7 @@ if (PHP_GRPC != "no") {
"src\\core\\lib\\gprpp\\stat_windows.cc " +
"src\\core\\lib\\gprpp\\thd_posix.cc " +
"src\\core\\lib\\gprpp\\thd_windows.cc " +
+ "src\\core\\lib\\gprpp\\time_util.cc " +
"src\\core\\lib\\http\\format_request.cc " +
"src\\core\\lib\\http\\httpcli.cc " +
"src\\core\\lib\\http\\httpcli_security_connector.cc " +
diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec
index a3283b09475..015d7e577b3 100644
--- a/gRPC-C++.podspec
+++ b/gRPC-C++.podspec
@@ -518,6 +518,7 @@ Pod::Spec.new do |s|
'src/core/lib/gprpp/stat.h',
'src/core/lib/gprpp/sync.h',
'src/core/lib/gprpp/thd.h',
+ 'src/core/lib/gprpp/time_util.h',
'src/core/lib/http/format_request.h',
'src/core/lib/http/httpcli.h',
'src/core/lib/http/parser.h',
@@ -1138,6 +1139,7 @@ Pod::Spec.new do |s|
'src/core/lib/gprpp/stat.h',
'src/core/lib/gprpp/sync.h',
'src/core/lib/gprpp/thd.h',
+ 'src/core/lib/gprpp/time_util.h',
'src/core/lib/http/format_request.h',
'src/core/lib/http/httpcli.h',
'src/core/lib/http/parser.h',
diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec
index 2c7bd3c64d3..781f82aaf80 100644
--- a/gRPC-Core.podspec
+++ b/gRPC-Core.podspec
@@ -852,6 +852,8 @@ Pod::Spec.new do |s|
'src/core/lib/gprpp/thd.h',
'src/core/lib/gprpp/thd_posix.cc',
'src/core/lib/gprpp/thd_windows.cc',
+ 'src/core/lib/gprpp/time_util.cc',
+ 'src/core/lib/gprpp/time_util.h',
'src/core/lib/http/format_request.cc',
'src/core/lib/http/format_request.h',
'src/core/lib/http/httpcli.cc',
@@ -1673,6 +1675,7 @@ Pod::Spec.new do |s|
'src/core/lib/gprpp/stat.h',
'src/core/lib/gprpp/sync.h',
'src/core/lib/gprpp/thd.h',
+ 'src/core/lib/gprpp/time_util.h',
'src/core/lib/http/format_request.h',
'src/core/lib/http/httpcli.h',
'src/core/lib/http/parser.h',
diff --git a/grpc.gemspec b/grpc.gemspec
index 0c479b92a1a..0f9169d66fa 100644
--- a/grpc.gemspec
+++ b/grpc.gemspec
@@ -767,6 +767,8 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/gprpp/thd.h )
s.files += %w( src/core/lib/gprpp/thd_posix.cc )
s.files += %w( src/core/lib/gprpp/thd_windows.cc )
+ s.files += %w( src/core/lib/gprpp/time_util.cc )
+ s.files += %w( src/core/lib/gprpp/time_util.h )
s.files += %w( src/core/lib/http/format_request.cc )
s.files += %w( src/core/lib/http/format_request.h )
s.files += %w( src/core/lib/http/httpcli.cc )
diff --git a/grpc.gyp b/grpc.gyp
index d94089d390f..c140299019a 100644
--- a/grpc.gyp
+++ b/grpc.gyp
@@ -431,6 +431,7 @@
'src/core/lib/gprpp/stat_windows.cc',
'src/core/lib/gprpp/thd_posix.cc',
'src/core/lib/gprpp/thd_windows.cc',
+ 'src/core/lib/gprpp/time_util.cc',
'src/core/lib/profiling/basic_timers.cc',
'src/core/lib/profiling/stap_timers.cc',
],
diff --git a/package.xml b/package.xml
index 5a884e53c09..fd094995511 100644
--- a/package.xml
+++ b/package.xml
@@ -747,6 +747,8 @@
+
+
diff --git a/src/core/lib/gprpp/time_util.cc b/src/core/lib/gprpp/time_util.cc
new file mode 100644
index 00000000000..d3aa25aefe2
--- /dev/null
+++ b/src/core/lib/gprpp/time_util.cc
@@ -0,0 +1,77 @@
+//
+// Copyright 2021 the gRPC authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include
+
+#include
+
+#include "src/core/lib/gprpp/time_util.h"
+
+namespace grpc_core {
+
+gpr_timespec ToGprTimeSpec(absl::Duration duration) {
+ if (duration == absl::InfiniteDuration()) {
+ return gpr_inf_future(GPR_TIMESPAN);
+ } else if (duration == -absl::InfiniteDuration()) {
+ return gpr_inf_past(GPR_TIMESPAN);
+ } else {
+ int64_t s = absl::IDivDuration(duration, absl::Seconds(1), &duration);
+ int64_t n = absl::IDivDuration(duration, absl::Nanoseconds(1), &duration);
+ return gpr_time_add(gpr_time_from_seconds(s, GPR_TIMESPAN),
+ gpr_time_from_nanos(n, GPR_TIMESPAN));
+ }
+}
+
+gpr_timespec ToGprTimeSpec(absl::Time time) {
+ if (time == absl::InfiniteFuture()) {
+ return gpr_inf_future(GPR_CLOCK_REALTIME);
+ } else if (time == absl::InfinitePast()) {
+ return gpr_inf_past(GPR_CLOCK_REALTIME);
+ } else {
+ timespec ts = absl::ToTimespec(time);
+ gpr_timespec out;
+ out.tv_sec = static_cast(ts.tv_sec);
+ out.tv_nsec = static_cast(ts.tv_nsec);
+ out.clock_type = GPR_CLOCK_REALTIME;
+ return out;
+ }
+}
+
+absl::Duration ToAbslDuration(gpr_timespec ts) {
+ GPR_ASSERT(ts.clock_type == GPR_TIMESPAN);
+ if (gpr_time_cmp(ts, gpr_inf_future(GPR_TIMESPAN)) == 0) {
+ return absl::InfiniteDuration();
+ } else if (gpr_time_cmp(ts, gpr_inf_past(GPR_TIMESPAN)) == 0) {
+ return -absl::InfiniteDuration();
+ } else {
+ return absl::Seconds(ts.tv_sec) + absl::Nanoseconds(ts.tv_nsec);
+ }
+}
+
+absl::Time ToAbslTime(gpr_timespec ts) {
+ GPR_ASSERT(ts.clock_type != GPR_TIMESPAN);
+ gpr_timespec rts = gpr_convert_clock_type(ts, GPR_CLOCK_REALTIME);
+ if (gpr_time_cmp(rts, gpr_inf_future(GPR_CLOCK_REALTIME)) == 0) {
+ return absl::InfiniteFuture();
+ } else if (gpr_time_cmp(rts, gpr_inf_past(GPR_CLOCK_REALTIME)) == 0) {
+ return absl::InfinitePast();
+ } else {
+ return absl::UnixEpoch() + absl::Seconds(rts.tv_sec) +
+ absl::Nanoseconds(rts.tv_nsec);
+ }
+}
+
+} // namespace grpc_core
diff --git a/src/core/lib/gprpp/time_util.h b/src/core/lib/gprpp/time_util.h
new file mode 100644
index 00000000000..4ae4a4076df
--- /dev/null
+++ b/src/core/lib/gprpp/time_util.h
@@ -0,0 +1,42 @@
+//
+// Copyright 2021 the gRPC authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#ifndef GRPC_CORE_LIB_GPRPP_TIME_UTIL_H
+#define GRPC_CORE_LIB_GPRPP_TIME_UTIL_H
+
+#include
+
+#include
+
+#include "absl/time/time.h"
+
+namespace grpc_core {
+
+// Converts absl::Duration to gpr_timespec(GPR_TIMESPAN)
+gpr_timespec ToGprTimeSpec(absl::Duration duration);
+
+// Converts absl::Time to gpr_timespec(GPR_CLOCK_REALTIME)
+gpr_timespec ToGprTimeSpec(absl::Time time);
+
+// Converts gpr_timespec(GPR_TIMESPAN) to absl::Duration
+absl::Duration ToAbslDuration(gpr_timespec ts);
+
+// Converts gpr_timespec(GPR_CLOCK_[MONOTONIC|REALTIME|PRECISE]) to absl::Time
+absl::Time ToAbslTime(gpr_timespec ts);
+
+} // namespace grpc_core
+
+#endif // GRPC_CORE_LIB_GPRPP_TIME_UTIL_H
diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py
index 48e0b95ee14..266b31e3a2a 100644
--- a/src/python/grpcio/grpc_core_dependencies.py
+++ b/src/python/grpcio/grpc_core_dependencies.py
@@ -360,6 +360,7 @@ CORE_SOURCE_FILES = [
'src/core/lib/gprpp/stat_windows.cc',
'src/core/lib/gprpp/thd_posix.cc',
'src/core/lib/gprpp/thd_windows.cc',
+ 'src/core/lib/gprpp/time_util.cc',
'src/core/lib/http/format_request.cc',
'src/core/lib/http/httpcli.cc',
'src/core/lib/http/httpcli_security_connector.cc',
diff --git a/test/core/gprpp/BUILD b/test/core/gprpp/BUILD
index 0db133bebd0..c0c3b5302eb 100644
--- a/test/core/gprpp/BUILD
+++ b/test/core/gprpp/BUILD
@@ -192,3 +192,17 @@ grpc_cc_test(
"//test/core/util:grpc_test_util",
],
)
+
+grpc_cc_test(
+ name = "time_util_test",
+ srcs = ["time_util_test.cc"],
+ external_deps = [
+ "gtest",
+ ],
+ language = "C++",
+ uses_polling = False,
+ deps = [
+ "//:gpr",
+ "//test/core/util:grpc_test_util",
+ ],
+)
diff --git a/test/core/gprpp/time_util_test.cc b/test/core/gprpp/time_util_test.cc
new file mode 100644
index 00000000000..4529147d662
--- /dev/null
+++ b/test/core/gprpp/time_util_test.cc
@@ -0,0 +1,134 @@
+//
+// Copyright 2021 the gRPC authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include
+#include
+
+#include
+
+#include
+
+#include "absl/time/time.h"
+
+#include "src/core/lib/gprpp/time_util.h"
+
+TEST(TimeUtilTest, ToGprTimeSpecFromAbslDurationWithRegularValues) {
+ std::vector times = {-10, -1, 0, 1, 10};
+ for (int t : times) {
+ EXPECT_EQ(0, gpr_time_cmp(gpr_time_from_nanos(t, GPR_TIMESPAN),
+ grpc_core::ToGprTimeSpec(absl::Nanoseconds(t))));
+ EXPECT_EQ(0, gpr_time_cmp(gpr_time_from_micros(t, GPR_TIMESPAN),
+ grpc_core::ToGprTimeSpec(absl::Microseconds(t))));
+ EXPECT_EQ(0, gpr_time_cmp(gpr_time_from_millis(t, GPR_TIMESPAN),
+ grpc_core::ToGprTimeSpec(absl::Milliseconds(t))));
+ EXPECT_EQ(0, gpr_time_cmp(gpr_time_from_seconds(t, GPR_TIMESPAN),
+ grpc_core::ToGprTimeSpec(absl::Seconds(t))));
+ EXPECT_EQ(0, gpr_time_cmp(gpr_time_from_minutes(t, GPR_TIMESPAN),
+ grpc_core::ToGprTimeSpec(absl::Minutes(t))));
+ EXPECT_EQ(0, gpr_time_cmp(gpr_time_from_hours(t, GPR_TIMESPAN),
+ grpc_core::ToGprTimeSpec(absl::Hours(t))));
+ }
+}
+
+TEST(TimeUtilTest, ToGprTimeSpecFromAbslDurationWithInfinites) {
+ EXPECT_EQ(0,
+ gpr_time_cmp(gpr_inf_past(GPR_TIMESPAN),
+ grpc_core::ToGprTimeSpec(-absl::InfiniteDuration())));
+ EXPECT_EQ(0, gpr_time_cmp(gpr_time_0(GPR_TIMESPAN),
+ grpc_core::ToGprTimeSpec(absl::ZeroDuration())));
+}
+
+TEST(TimeUtilTest, ToGprTimeSpecFromAbslTimeWithRegularValues) {
+ std::vector times = {0, 10, 100000000};
+ for (int t : times) {
+ EXPECT_EQ(0,
+ gpr_time_cmp(gpr_time_from_nanos(t, GPR_CLOCK_REALTIME),
+ grpc_core::ToGprTimeSpec(absl::FromUnixNanos(t))));
+ EXPECT_EQ(0,
+ gpr_time_cmp(gpr_time_from_micros(t, GPR_CLOCK_REALTIME),
+ grpc_core::ToGprTimeSpec(absl::FromUnixMicros(t))));
+ EXPECT_EQ(0,
+ gpr_time_cmp(gpr_time_from_millis(t, GPR_CLOCK_REALTIME),
+ grpc_core::ToGprTimeSpec(absl::FromUnixMillis(t))));
+ EXPECT_EQ(0,
+ gpr_time_cmp(gpr_time_from_seconds(t, GPR_CLOCK_REALTIME),
+ grpc_core::ToGprTimeSpec(absl::FromUnixSeconds(t))));
+ }
+}
+
+TEST(TimeUtilTest, ToGprTimeSpecFromAbslTimeWithInfinites) {
+ EXPECT_EQ(0, gpr_time_cmp(gpr_inf_future(GPR_CLOCK_REALTIME),
+ grpc_core::ToGprTimeSpec(absl::InfiniteFuture())));
+ EXPECT_EQ(0, gpr_time_cmp(gpr_inf_past(GPR_CLOCK_REALTIME),
+ grpc_core::ToGprTimeSpec(absl::InfinitePast())));
+}
+
+TEST(TimeUtilTest, ToAbslDurationWithRegularValues) {
+ std::vector times = {-10, -1, 0, 1, 10};
+ for (int t : times) {
+ EXPECT_EQ(absl::Nanoseconds(t),
+ grpc_core::ToAbslDuration(gpr_time_from_nanos(t, GPR_TIMESPAN)));
+ EXPECT_EQ(absl::Microseconds(t),
+ grpc_core::ToAbslDuration(gpr_time_from_micros(t, GPR_TIMESPAN)));
+ EXPECT_EQ(absl::Milliseconds(t),
+ grpc_core::ToAbslDuration(gpr_time_from_millis(t, GPR_TIMESPAN)));
+ EXPECT_EQ(absl::Seconds(t), grpc_core::ToAbslDuration(
+ gpr_time_from_seconds(t, GPR_TIMESPAN)));
+ EXPECT_EQ(absl::Minutes(t), grpc_core::ToAbslDuration(
+ gpr_time_from_minutes(t, GPR_TIMESPAN)));
+ EXPECT_EQ(absl::Hours(t),
+ grpc_core::ToAbslDuration(gpr_time_from_hours(t, GPR_TIMESPAN)));
+ }
+}
+
+TEST(TimeUtilTest, ToAbslDurationWithInfinites) {
+ EXPECT_EQ(absl::InfiniteDuration(),
+ grpc_core::ToAbslDuration(gpr_inf_future(GPR_TIMESPAN)));
+ EXPECT_EQ(-absl::InfiniteDuration(),
+ grpc_core::ToAbslDuration(gpr_inf_past(GPR_TIMESPAN)));
+}
+
+TEST(TimeUtilTest, ToAbslTimeWithRegularValues) {
+ std::vector times = {0, 10, 100000000};
+ for (int t : times) {
+ EXPECT_EQ(absl::FromUnixNanos(t), grpc_core::ToAbslTime(gpr_time_from_nanos(
+ t, GPR_CLOCK_REALTIME)));
+ EXPECT_EQ(
+ absl::FromUnixMicros(t),
+ grpc_core::ToAbslTime(gpr_time_from_micros(t, GPR_CLOCK_REALTIME)));
+ EXPECT_EQ(
+ absl::FromUnixMillis(t),
+ grpc_core::ToAbslTime(gpr_time_from_millis(t, GPR_CLOCK_REALTIME)));
+ EXPECT_EQ(
+ absl::FromUnixSeconds(t),
+ grpc_core::ToAbslTime(gpr_time_from_seconds(t, GPR_CLOCK_REALTIME)));
+ }
+}
+
+TEST(TimeUtilTest, ToAbslTimeWithInfinites) {
+ EXPECT_EQ(absl::InfiniteFuture(),
+ grpc_core::ToAbslTime(gpr_inf_future(GPR_CLOCK_REALTIME)));
+ EXPECT_EQ(absl::InfinitePast(),
+ grpc_core::ToAbslTime(gpr_inf_past(GPR_CLOCK_REALTIME)));
+ EXPECT_EQ(absl::UnixEpoch(),
+ grpc_core::ToAbslTime(gpr_time_0(GPR_CLOCK_REALTIME)));
+}
+
+int main(int argc, char** argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ int ret = RUN_ALL_TESTS();
+ return ret;
+}
diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal
index c0fb2e6192f..261e8a87506 100644
--- a/tools/doxygen/Doxyfile.c++.internal
+++ b/tools/doxygen/Doxyfile.c++.internal
@@ -1698,6 +1698,8 @@ src/core/lib/gprpp/sync.h \
src/core/lib/gprpp/thd.h \
src/core/lib/gprpp/thd_posix.cc \
src/core/lib/gprpp/thd_windows.cc \
+src/core/lib/gprpp/time_util.cc \
+src/core/lib/gprpp/time_util.h \
src/core/lib/http/format_request.cc \
src/core/lib/http/format_request.h \
src/core/lib/http/httpcli.cc \
diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal
index 052025d147f..f2d8871520d 100644
--- a/tools/doxygen/Doxyfile.core.internal
+++ b/tools/doxygen/Doxyfile.core.internal
@@ -1538,6 +1538,8 @@ src/core/lib/gprpp/sync.h \
src/core/lib/gprpp/thd.h \
src/core/lib/gprpp/thd_posix.cc \
src/core/lib/gprpp/thd_windows.cc \
+src/core/lib/gprpp/time_util.cc \
+src/core/lib/gprpp/time_util.h \
src/core/lib/http/format_request.cc \
src/core/lib/http/format_request.h \
src/core/lib/http/httpcli.cc \
diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json
index b584b30224f..43894a90aa7 100644
--- a/tools/run_tests/generated/tests.json
+++ b/tools/run_tests/generated/tests.json
@@ -6183,6 +6183,30 @@
],
"uses_polling": true
},
+ {
+ "args": [],
+ "benchmark": false,
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix",
+ "windows"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "gtest": true,
+ "language": "c++",
+ "name": "time_util_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix",
+ "windows"
+ ],
+ "uses_polling": false
+ },
{
"args": [],
"benchmark": false,