1 // Copyright 2017 The Abseil Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "absl/time/time.h"
16
17 #if defined(_MSC_VER)
18 #include <winsock2.h> // for timeval
19 #endif
20
21 #include <chrono> // NOLINT(build/c++11)
22 #include <cstring>
23 #include <ctime>
24 #include <iomanip>
25 #include <limits>
26 #include <string>
27
28 #include "gmock/gmock.h"
29 #include "gtest/gtest.h"
30 #include "absl/numeric/int128.h"
31 #include "absl/time/clock.h"
32 #include "absl/time/internal/test_util.h"
33
34 namespace {
35
36 #if defined(GTEST_USES_SIMPLE_RE) && GTEST_USES_SIMPLE_RE
37 const char kZoneAbbrRE[] = ".*"; // just punt
38 #else
39 const char kZoneAbbrRE[] = "[A-Za-z]{3,4}|[-+][0-9]{2}([0-9]{2})?";
40 #endif
41
42 // This helper is a macro so that failed expectations show up with the
43 // correct line numbers.
44 #define EXPECT_CIVIL_INFO(ci, y, m, d, h, min, s, off, isdst) \
45 do { \
46 EXPECT_EQ(y, ci.cs.year()); \
47 EXPECT_EQ(m, ci.cs.month()); \
48 EXPECT_EQ(d, ci.cs.day()); \
49 EXPECT_EQ(h, ci.cs.hour()); \
50 EXPECT_EQ(min, ci.cs.minute()); \
51 EXPECT_EQ(s, ci.cs.second()); \
52 EXPECT_EQ(off, ci.offset); \
53 EXPECT_EQ(isdst, ci.is_dst); \
54 EXPECT_THAT(ci.zone_abbr, testing::MatchesRegex(kZoneAbbrRE)); \
55 } while (0)
56
57 // A gMock matcher to match timespec values. Use this matcher like:
58 // timespec ts1, ts2;
59 // EXPECT_THAT(ts1, TimespecMatcher(ts2));
60 MATCHER_P(TimespecMatcher, ts, "") {
61 if (ts.tv_sec == arg.tv_sec && ts.tv_nsec == arg.tv_nsec)
62 return true;
63 *result_listener << "expected: {" << ts.tv_sec << ", " << ts.tv_nsec << "} ";
64 *result_listener << "actual: {" << arg.tv_sec << ", " << arg.tv_nsec << "}";
65 return false;
66 }
67
68 // A gMock matcher to match timeval values. Use this matcher like:
69 // timeval tv1, tv2;
70 // EXPECT_THAT(tv1, TimevalMatcher(tv2));
71 MATCHER_P(TimevalMatcher, tv, "") {
72 if (tv.tv_sec == arg.tv_sec && tv.tv_usec == arg.tv_usec)
73 return true;
74 *result_listener << "expected: {" << tv.tv_sec << ", " << tv.tv_usec << "} ";
75 *result_listener << "actual: {" << arg.tv_sec << ", " << arg.tv_usec << "}";
76 return false;
77 }
78
TEST(Time,ConstExpr)79 TEST(Time, ConstExpr) {
80 constexpr absl::Time t0 = absl::UnixEpoch();
81 static_assert(t0 == absl::Time(), "UnixEpoch");
82 constexpr absl::Time t1 = absl::InfiniteFuture();
83 static_assert(t1 != absl::Time(), "InfiniteFuture");
84 constexpr absl::Time t2 = absl::InfinitePast();
85 static_assert(t2 != absl::Time(), "InfinitePast");
86 constexpr absl::Time t3 = absl::FromUnixNanos(0);
87 static_assert(t3 == absl::Time(), "FromUnixNanos");
88 constexpr absl::Time t4 = absl::FromUnixMicros(0);
89 static_assert(t4 == absl::Time(), "FromUnixMicros");
90 constexpr absl::Time t5 = absl::FromUnixMillis(0);
91 static_assert(t5 == absl::Time(), "FromUnixMillis");
92 constexpr absl::Time t6 = absl::FromUnixSeconds(0);
93 static_assert(t6 == absl::Time(), "FromUnixSeconds");
94 constexpr absl::Time t7 = absl::FromTimeT(0);
95 static_assert(t7 == absl::Time(), "FromTimeT");
96 }
97
TEST(Time,ValueSemantics)98 TEST(Time, ValueSemantics) {
99 absl::Time a; // Default construction
100 absl::Time b = a; // Copy construction
101 EXPECT_EQ(a, b);
102 absl::Time c(a); // Copy construction (again)
103 EXPECT_EQ(a, b);
104 EXPECT_EQ(a, c);
105 EXPECT_EQ(b, c);
106 b = c; // Assignment
107 EXPECT_EQ(a, b);
108 EXPECT_EQ(a, c);
109 EXPECT_EQ(b, c);
110 }
111
TEST(Time,UnixEpoch)112 TEST(Time, UnixEpoch) {
113 const auto ci = absl::UTCTimeZone().At(absl::UnixEpoch());
114 EXPECT_EQ(absl::CivilSecond(1970, 1, 1, 0, 0, 0), ci.cs);
115 EXPECT_EQ(absl::ZeroDuration(), ci.subsecond);
116 EXPECT_EQ(absl::Weekday::thursday, absl::GetWeekday(ci.cs));
117 }
118
TEST(Time,Breakdown)119 TEST(Time, Breakdown) {
120 absl::TimeZone tz = absl::time_internal::LoadTimeZone("America/New_York");
121 absl::Time t = absl::UnixEpoch();
122
123 // The Unix epoch as seen in NYC.
124 auto ci = tz.At(t);
125 EXPECT_CIVIL_INFO(ci, 1969, 12, 31, 19, 0, 0, -18000, false);
126 EXPECT_EQ(absl::ZeroDuration(), ci.subsecond);
127 EXPECT_EQ(absl::Weekday::wednesday, absl::GetWeekday(ci.cs));
128
129 // Just before the epoch.
130 t -= absl::Nanoseconds(1);
131 ci = tz.At(t);
132 EXPECT_CIVIL_INFO(ci, 1969, 12, 31, 18, 59, 59, -18000, false);
133 EXPECT_EQ(absl::Nanoseconds(999999999), ci.subsecond);
134 EXPECT_EQ(absl::Weekday::wednesday, absl::GetWeekday(ci.cs));
135
136 // Some time later.
137 t += absl::Hours(24) * 2735;
138 t += absl::Hours(18) + absl::Minutes(30) + absl::Seconds(15) +
139 absl::Nanoseconds(9);
140 ci = tz.At(t);
141 EXPECT_CIVIL_INFO(ci, 1977, 6, 28, 14, 30, 15, -14400, true);
142 EXPECT_EQ(8, ci.subsecond / absl::Nanoseconds(1));
143 EXPECT_EQ(absl::Weekday::tuesday, absl::GetWeekday(ci.cs));
144 }
145
TEST(Time,AdditiveOperators)146 TEST(Time, AdditiveOperators) {
147 const absl::Duration d = absl::Nanoseconds(1);
148 const absl::Time t0;
149 const absl::Time t1 = t0 + d;
150
151 EXPECT_EQ(d, t1 - t0);
152 EXPECT_EQ(-d, t0 - t1);
153 EXPECT_EQ(t0, t1 - d);
154
155 absl::Time t(t0);
156 EXPECT_EQ(t0, t);
157 t += d;
158 EXPECT_EQ(t0 + d, t);
159 EXPECT_EQ(d, t - t0);
160 t -= d;
161 EXPECT_EQ(t0, t);
162
163 // Tests overflow between subseconds and seconds.
164 t = absl::UnixEpoch();
165 t += absl::Milliseconds(500);
166 EXPECT_EQ(absl::UnixEpoch() + absl::Milliseconds(500), t);
167 t += absl::Milliseconds(600);
168 EXPECT_EQ(absl::UnixEpoch() + absl::Milliseconds(1100), t);
169 t -= absl::Milliseconds(600);
170 EXPECT_EQ(absl::UnixEpoch() + absl::Milliseconds(500), t);
171 t -= absl::Milliseconds(500);
172 EXPECT_EQ(absl::UnixEpoch(), t);
173 }
174
TEST(Time,RelationalOperators)175 TEST(Time, RelationalOperators) {
176 constexpr absl::Time t1 = absl::FromUnixNanos(0);
177 constexpr absl::Time t2 = absl::FromUnixNanos(1);
178 constexpr absl::Time t3 = absl::FromUnixNanos(2);
179
180 static_assert(absl::Time() == t1, "");
181 static_assert(t1 == t1, "");
182 static_assert(t2 == t2, "");
183 static_assert(t3 == t3, "");
184
185 static_assert(t1 < t2, "");
186 static_assert(t2 < t3, "");
187 static_assert(t1 < t3, "");
188
189 static_assert(t1 <= t1, "");
190 static_assert(t1 <= t2, "");
191 static_assert(t2 <= t2, "");
192 static_assert(t2 <= t3, "");
193 static_assert(t3 <= t3, "");
194 static_assert(t1 <= t3, "");
195
196 static_assert(t2 > t1, "");
197 static_assert(t3 > t2, "");
198 static_assert(t3 > t1, "");
199
200 static_assert(t2 >= t2, "");
201 static_assert(t2 >= t1, "");
202 static_assert(t3 >= t3, "");
203 static_assert(t3 >= t2, "");
204 static_assert(t1 >= t1, "");
205 static_assert(t3 >= t1, "");
206 }
207
TEST(Time,Infinity)208 TEST(Time, Infinity) {
209 constexpr absl::Time ifuture = absl::InfiniteFuture();
210 constexpr absl::Time ipast = absl::InfinitePast();
211
212 static_assert(ifuture == ifuture, "");
213 static_assert(ipast == ipast, "");
214 static_assert(ipast < ifuture, "");
215 static_assert(ifuture > ipast, "");
216
217 // Arithmetic saturates
218 EXPECT_EQ(ifuture, ifuture + absl::Seconds(1));
219 EXPECT_EQ(ifuture, ifuture - absl::Seconds(1));
220 EXPECT_EQ(ipast, ipast + absl::Seconds(1));
221 EXPECT_EQ(ipast, ipast - absl::Seconds(1));
222
223 EXPECT_EQ(absl::InfiniteDuration(), ifuture - ifuture);
224 EXPECT_EQ(absl::InfiniteDuration(), ifuture - ipast);
225 EXPECT_EQ(-absl::InfiniteDuration(), ipast - ifuture);
226 EXPECT_EQ(-absl::InfiniteDuration(), ipast - ipast);
227
228 constexpr absl::Time t = absl::UnixEpoch(); // Any finite time.
229 static_assert(t < ifuture, "");
230 static_assert(t > ipast, "");
231 }
232
TEST(Time,FloorConversion)233 TEST(Time, FloorConversion) {
234 #define TEST_FLOOR_CONVERSION(TO, FROM) \
235 EXPECT_EQ(1, TO(FROM(1001))); \
236 EXPECT_EQ(1, TO(FROM(1000))); \
237 EXPECT_EQ(0, TO(FROM(999))); \
238 EXPECT_EQ(0, TO(FROM(1))); \
239 EXPECT_EQ(0, TO(FROM(0))); \
240 EXPECT_EQ(-1, TO(FROM(-1))); \
241 EXPECT_EQ(-1, TO(FROM(-999))); \
242 EXPECT_EQ(-1, TO(FROM(-1000))); \
243 EXPECT_EQ(-2, TO(FROM(-1001)));
244
245 TEST_FLOOR_CONVERSION(absl::ToUnixMicros, absl::FromUnixNanos);
246 TEST_FLOOR_CONVERSION(absl::ToUnixMillis, absl::FromUnixMicros);
247 TEST_FLOOR_CONVERSION(absl::ToUnixSeconds, absl::FromUnixMillis);
248 TEST_FLOOR_CONVERSION(absl::ToTimeT, absl::FromUnixMillis);
249
250 #undef TEST_FLOOR_CONVERSION
251
252 // Tests ToUnixNanos.
253 EXPECT_EQ(1, absl::ToUnixNanos(absl::UnixEpoch() + absl::Nanoseconds(3) / 2));
254 EXPECT_EQ(1, absl::ToUnixNanos(absl::UnixEpoch() + absl::Nanoseconds(1)));
255 EXPECT_EQ(0, absl::ToUnixNanos(absl::UnixEpoch() + absl::Nanoseconds(1) / 2));
256 EXPECT_EQ(0, absl::ToUnixNanos(absl::UnixEpoch() + absl::Nanoseconds(0)));
257 EXPECT_EQ(-1,
258 absl::ToUnixNanos(absl::UnixEpoch() - absl::Nanoseconds(1) / 2));
259 EXPECT_EQ(-1, absl::ToUnixNanos(absl::UnixEpoch() - absl::Nanoseconds(1)));
260 EXPECT_EQ(-2,
261 absl::ToUnixNanos(absl::UnixEpoch() - absl::Nanoseconds(3) / 2));
262
263 // Tests ToUniversal, which uses a different epoch than the tests above.
264 EXPECT_EQ(1,
265 absl::ToUniversal(absl::UniversalEpoch() + absl::Nanoseconds(101)));
266 EXPECT_EQ(1,
267 absl::ToUniversal(absl::UniversalEpoch() + absl::Nanoseconds(100)));
268 EXPECT_EQ(0,
269 absl::ToUniversal(absl::UniversalEpoch() + absl::Nanoseconds(99)));
270 EXPECT_EQ(0,
271 absl::ToUniversal(absl::UniversalEpoch() + absl::Nanoseconds(1)));
272 EXPECT_EQ(0,
273 absl::ToUniversal(absl::UniversalEpoch() + absl::Nanoseconds(0)));
274 EXPECT_EQ(-1,
275 absl::ToUniversal(absl::UniversalEpoch() + absl::Nanoseconds(-1)));
276 EXPECT_EQ(-1,
277 absl::ToUniversal(absl::UniversalEpoch() + absl::Nanoseconds(-99)));
278 EXPECT_EQ(
279 -1, absl::ToUniversal(absl::UniversalEpoch() + absl::Nanoseconds(-100)));
280 EXPECT_EQ(
281 -2, absl::ToUniversal(absl::UniversalEpoch() + absl::Nanoseconds(-101)));
282
283 // Tests ToTimespec()/TimeFromTimespec()
284 const struct {
285 absl::Time t;
286 timespec ts;
287 } to_ts[] = {
288 {absl::FromUnixSeconds(1) + absl::Nanoseconds(1), {1, 1}},
289 {absl::FromUnixSeconds(1) + absl::Nanoseconds(1) / 2, {1, 0}},
290 {absl::FromUnixSeconds(1) + absl::Nanoseconds(0), {1, 0}},
291 {absl::FromUnixSeconds(0) + absl::Nanoseconds(0), {0, 0}},
292 {absl::FromUnixSeconds(0) - absl::Nanoseconds(1) / 2, {-1, 999999999}},
293 {absl::FromUnixSeconds(0) - absl::Nanoseconds(1), {-1, 999999999}},
294 {absl::FromUnixSeconds(-1) + absl::Nanoseconds(1), {-1, 1}},
295 {absl::FromUnixSeconds(-1) + absl::Nanoseconds(1) / 2, {-1, 0}},
296 {absl::FromUnixSeconds(-1) + absl::Nanoseconds(0), {-1, 0}},
297 {absl::FromUnixSeconds(-1) - absl::Nanoseconds(1) / 2, {-2, 999999999}},
298 };
299 for (const auto& test : to_ts) {
300 EXPECT_THAT(absl::ToTimespec(test.t), TimespecMatcher(test.ts));
301 }
302 const struct {
303 timespec ts;
304 absl::Time t;
305 } from_ts[] = {
306 {{1, 1}, absl::FromUnixSeconds(1) + absl::Nanoseconds(1)},
307 {{1, 0}, absl::FromUnixSeconds(1) + absl::Nanoseconds(0)},
308 {{0, 0}, absl::FromUnixSeconds(0) + absl::Nanoseconds(0)},
309 {{0, -1}, absl::FromUnixSeconds(0) - absl::Nanoseconds(1)},
310 {{-1, 999999999}, absl::FromUnixSeconds(0) - absl::Nanoseconds(1)},
311 {{-1, 1}, absl::FromUnixSeconds(-1) + absl::Nanoseconds(1)},
312 {{-1, 0}, absl::FromUnixSeconds(-1) + absl::Nanoseconds(0)},
313 {{-1, -1}, absl::FromUnixSeconds(-1) - absl::Nanoseconds(1)},
314 {{-2, 999999999}, absl::FromUnixSeconds(-1) - absl::Nanoseconds(1)},
315 };
316 for (const auto& test : from_ts) {
317 EXPECT_EQ(test.t, absl::TimeFromTimespec(test.ts));
318 }
319
320 // Tests ToTimeval()/TimeFromTimeval() (same as timespec above)
321 const struct {
322 absl::Time t;
323 timeval tv;
324 } to_tv[] = {
325 {absl::FromUnixSeconds(1) + absl::Microseconds(1), {1, 1}},
326 {absl::FromUnixSeconds(1) + absl::Microseconds(1) / 2, {1, 0}},
327 {absl::FromUnixSeconds(1) + absl::Microseconds(0), {1, 0}},
328 {absl::FromUnixSeconds(0) + absl::Microseconds(0), {0, 0}},
329 {absl::FromUnixSeconds(0) - absl::Microseconds(1) / 2, {-1, 999999}},
330 {absl::FromUnixSeconds(0) - absl::Microseconds(1), {-1, 999999}},
331 {absl::FromUnixSeconds(-1) + absl::Microseconds(1), {-1, 1}},
332 {absl::FromUnixSeconds(-1) + absl::Microseconds(1) / 2, {-1, 0}},
333 {absl::FromUnixSeconds(-1) + absl::Microseconds(0), {-1, 0}},
334 {absl::FromUnixSeconds(-1) - absl::Microseconds(1) / 2, {-2, 999999}},
335 };
336 for (const auto& test : to_tv) {
337 EXPECT_THAT(ToTimeval(test.t), TimevalMatcher(test.tv));
338 }
339 const struct {
340 timeval tv;
341 absl::Time t;
342 } from_tv[] = {
343 {{1, 1}, absl::FromUnixSeconds(1) + absl::Microseconds(1)},
344 {{1, 0}, absl::FromUnixSeconds(1) + absl::Microseconds(0)},
345 {{0, 0}, absl::FromUnixSeconds(0) + absl::Microseconds(0)},
346 {{0, -1}, absl::FromUnixSeconds(0) - absl::Microseconds(1)},
347 {{-1, 999999}, absl::FromUnixSeconds(0) - absl::Microseconds(1)},
348 {{-1, 1}, absl::FromUnixSeconds(-1) + absl::Microseconds(1)},
349 {{-1, 0}, absl::FromUnixSeconds(-1) + absl::Microseconds(0)},
350 {{-1, -1}, absl::FromUnixSeconds(-1) - absl::Microseconds(1)},
351 {{-2, 999999}, absl::FromUnixSeconds(-1) - absl::Microseconds(1)},
352 };
353 for (const auto& test : from_tv) {
354 EXPECT_EQ(test.t, absl::TimeFromTimeval(test.tv));
355 }
356
357 // Tests flooring near negative infinity.
358 const int64_t min_plus_1 = std::numeric_limits<int64_t>::min() + 1;
359 EXPECT_EQ(min_plus_1, absl::ToUnixSeconds(absl::FromUnixSeconds(min_plus_1)));
360 EXPECT_EQ(std::numeric_limits<int64_t>::min(),
361 absl::ToUnixSeconds(
362 absl::FromUnixSeconds(min_plus_1) - absl::Nanoseconds(1) / 2));
363
364 // Tests flooring near positive infinity.
365 EXPECT_EQ(std::numeric_limits<int64_t>::max(),
366 absl::ToUnixSeconds(absl::FromUnixSeconds(
367 std::numeric_limits<int64_t>::max()) + absl::Nanoseconds(1) / 2));
368 EXPECT_EQ(std::numeric_limits<int64_t>::max(),
369 absl::ToUnixSeconds(
370 absl::FromUnixSeconds(std::numeric_limits<int64_t>::max())));
371 EXPECT_EQ(std::numeric_limits<int64_t>::max() - 1,
372 absl::ToUnixSeconds(absl::FromUnixSeconds(
373 std::numeric_limits<int64_t>::max()) - absl::Nanoseconds(1) / 2));
374 }
375
TEST(Time,RoundtripConversion)376 TEST(Time, RoundtripConversion) {
377 #define TEST_CONVERSION_ROUND_TRIP(SOURCE, FROM, TO, MATCHER) \
378 EXPECT_THAT(TO(FROM(SOURCE)), MATCHER(SOURCE))
379
380 // FromUnixNanos() and ToUnixNanos()
381 int64_t now_ns = absl::GetCurrentTimeNanos();
382 TEST_CONVERSION_ROUND_TRIP(-1, absl::FromUnixNanos, absl::ToUnixNanos,
383 testing::Eq);
384 TEST_CONVERSION_ROUND_TRIP(0, absl::FromUnixNanos, absl::ToUnixNanos,
385 testing::Eq);
386 TEST_CONVERSION_ROUND_TRIP(1, absl::FromUnixNanos, absl::ToUnixNanos,
387 testing::Eq);
388 TEST_CONVERSION_ROUND_TRIP(now_ns, absl::FromUnixNanos, absl::ToUnixNanos,
389 testing::Eq)
390 << now_ns;
391
392 // FromUnixMicros() and ToUnixMicros()
393 int64_t now_us = absl::GetCurrentTimeNanos() / 1000;
394 TEST_CONVERSION_ROUND_TRIP(-1, absl::FromUnixMicros, absl::ToUnixMicros,
395 testing::Eq);
396 TEST_CONVERSION_ROUND_TRIP(0, absl::FromUnixMicros, absl::ToUnixMicros,
397 testing::Eq);
398 TEST_CONVERSION_ROUND_TRIP(1, absl::FromUnixMicros, absl::ToUnixMicros,
399 testing::Eq);
400 TEST_CONVERSION_ROUND_TRIP(now_us, absl::FromUnixMicros, absl::ToUnixMicros,
401 testing::Eq)
402 << now_us;
403
404 // FromUnixMillis() and ToUnixMillis()
405 int64_t now_ms = absl::GetCurrentTimeNanos() / 1000000;
406 TEST_CONVERSION_ROUND_TRIP(-1, absl::FromUnixMillis, absl::ToUnixMillis,
407 testing::Eq);
408 TEST_CONVERSION_ROUND_TRIP(0, absl::FromUnixMillis, absl::ToUnixMillis,
409 testing::Eq);
410 TEST_CONVERSION_ROUND_TRIP(1, absl::FromUnixMillis, absl::ToUnixMillis,
411 testing::Eq);
412 TEST_CONVERSION_ROUND_TRIP(now_ms, absl::FromUnixMillis, absl::ToUnixMillis,
413 testing::Eq)
414 << now_ms;
415
416 // FromUnixSeconds() and ToUnixSeconds()
417 int64_t now_s = std::time(nullptr);
418 TEST_CONVERSION_ROUND_TRIP(-1, absl::FromUnixSeconds, absl::ToUnixSeconds,
419 testing::Eq);
420 TEST_CONVERSION_ROUND_TRIP(0, absl::FromUnixSeconds, absl::ToUnixSeconds,
421 testing::Eq);
422 TEST_CONVERSION_ROUND_TRIP(1, absl::FromUnixSeconds, absl::ToUnixSeconds,
423 testing::Eq);
424 TEST_CONVERSION_ROUND_TRIP(now_s, absl::FromUnixSeconds, absl::ToUnixSeconds,
425 testing::Eq)
426 << now_s;
427
428 // FromTimeT() and ToTimeT()
429 time_t now_time_t = std::time(nullptr);
430 TEST_CONVERSION_ROUND_TRIP(-1, absl::FromTimeT, absl::ToTimeT, testing::Eq);
431 TEST_CONVERSION_ROUND_TRIP(0, absl::FromTimeT, absl::ToTimeT, testing::Eq);
432 TEST_CONVERSION_ROUND_TRIP(1, absl::FromTimeT, absl::ToTimeT, testing::Eq);
433 TEST_CONVERSION_ROUND_TRIP(now_time_t, absl::FromTimeT, absl::ToTimeT,
434 testing::Eq)
435 << now_time_t;
436
437 // TimeFromTimeval() and ToTimeval()
438 timeval tv;
439 tv.tv_sec = -1;
440 tv.tv_usec = 0;
441 TEST_CONVERSION_ROUND_TRIP(tv, absl::TimeFromTimeval, absl::ToTimeval,
442 TimevalMatcher);
443 tv.tv_sec = -1;
444 tv.tv_usec = 999999;
445 TEST_CONVERSION_ROUND_TRIP(tv, absl::TimeFromTimeval, absl::ToTimeval,
446 TimevalMatcher);
447 tv.tv_sec = 0;
448 tv.tv_usec = 0;
449 TEST_CONVERSION_ROUND_TRIP(tv, absl::TimeFromTimeval, absl::ToTimeval,
450 TimevalMatcher);
451 tv.tv_sec = 0;
452 tv.tv_usec = 1;
453 TEST_CONVERSION_ROUND_TRIP(tv, absl::TimeFromTimeval, absl::ToTimeval,
454 TimevalMatcher);
455 tv.tv_sec = 1;
456 tv.tv_usec = 0;
457 TEST_CONVERSION_ROUND_TRIP(tv, absl::TimeFromTimeval, absl::ToTimeval,
458 TimevalMatcher);
459
460 // TimeFromTimespec() and ToTimespec()
461 timespec ts;
462 ts.tv_sec = -1;
463 ts.tv_nsec = 0;
464 TEST_CONVERSION_ROUND_TRIP(ts, absl::TimeFromTimespec, absl::ToTimespec,
465 TimespecMatcher);
466 ts.tv_sec = -1;
467 ts.tv_nsec = 999999999;
468 TEST_CONVERSION_ROUND_TRIP(ts, absl::TimeFromTimespec, absl::ToTimespec,
469 TimespecMatcher);
470 ts.tv_sec = 0;
471 ts.tv_nsec = 0;
472 TEST_CONVERSION_ROUND_TRIP(ts, absl::TimeFromTimespec, absl::ToTimespec,
473 TimespecMatcher);
474 ts.tv_sec = 0;
475 ts.tv_nsec = 1;
476 TEST_CONVERSION_ROUND_TRIP(ts, absl::TimeFromTimespec, absl::ToTimespec,
477 TimespecMatcher);
478 ts.tv_sec = 1;
479 ts.tv_nsec = 0;
480 TEST_CONVERSION_ROUND_TRIP(ts, absl::TimeFromTimespec, absl::ToTimespec,
481 TimespecMatcher);
482
483 // FromUDate() and ToUDate()
484 double now_ud = absl::GetCurrentTimeNanos() / 1000000;
485 TEST_CONVERSION_ROUND_TRIP(-1.5, absl::FromUDate, absl::ToUDate,
486 testing::DoubleEq);
487 TEST_CONVERSION_ROUND_TRIP(-1, absl::FromUDate, absl::ToUDate,
488 testing::DoubleEq);
489 TEST_CONVERSION_ROUND_TRIP(-0.5, absl::FromUDate, absl::ToUDate,
490 testing::DoubleEq);
491 TEST_CONVERSION_ROUND_TRIP(0, absl::FromUDate, absl::ToUDate,
492 testing::DoubleEq);
493 TEST_CONVERSION_ROUND_TRIP(0.5, absl::FromUDate, absl::ToUDate,
494 testing::DoubleEq);
495 TEST_CONVERSION_ROUND_TRIP(1, absl::FromUDate, absl::ToUDate,
496 testing::DoubleEq);
497 TEST_CONVERSION_ROUND_TRIP(1.5, absl::FromUDate, absl::ToUDate,
498 testing::DoubleEq);
499 TEST_CONVERSION_ROUND_TRIP(now_ud, absl::FromUDate, absl::ToUDate,
500 testing::DoubleEq)
501 << std::fixed << std::setprecision(17) << now_ud;
502
503 // FromUniversal() and ToUniversal()
504 int64_t now_uni = ((719162LL * (24 * 60 * 60)) * (1000 * 1000 * 10)) +
505 (absl::GetCurrentTimeNanos() / 100);
506 TEST_CONVERSION_ROUND_TRIP(-1, absl::FromUniversal, absl::ToUniversal,
507 testing::Eq);
508 TEST_CONVERSION_ROUND_TRIP(0, absl::FromUniversal, absl::ToUniversal,
509 testing::Eq);
510 TEST_CONVERSION_ROUND_TRIP(1, absl::FromUniversal, absl::ToUniversal,
511 testing::Eq);
512 TEST_CONVERSION_ROUND_TRIP(now_uni, absl::FromUniversal, absl::ToUniversal,
513 testing::Eq)
514 << now_uni;
515
516 #undef TEST_CONVERSION_ROUND_TRIP
517 }
518
519 template <typename Duration>
MakeChronoUnixTime(const Duration & d)520 std::chrono::system_clock::time_point MakeChronoUnixTime(const Duration& d) {
521 return std::chrono::system_clock::from_time_t(0) + d;
522 }
523
TEST(Time,FromChrono)524 TEST(Time, FromChrono) {
525 EXPECT_EQ(absl::FromTimeT(-1),
526 absl::FromChrono(std::chrono::system_clock::from_time_t(-1)));
527 EXPECT_EQ(absl::FromTimeT(0),
528 absl::FromChrono(std::chrono::system_clock::from_time_t(0)));
529 EXPECT_EQ(absl::FromTimeT(1),
530 absl::FromChrono(std::chrono::system_clock::from_time_t(1)));
531
532 EXPECT_EQ(
533 absl::FromUnixMillis(-1),
534 absl::FromChrono(MakeChronoUnixTime(std::chrono::milliseconds(-1))));
535 EXPECT_EQ(absl::FromUnixMillis(0),
536 absl::FromChrono(MakeChronoUnixTime(std::chrono::milliseconds(0))));
537 EXPECT_EQ(absl::FromUnixMillis(1),
538 absl::FromChrono(MakeChronoUnixTime(std::chrono::milliseconds(1))));
539
540 // Chrono doesn't define exactly its range and precision (neither does
541 // absl::Time), so let's simply test +/- ~100 years to make sure things work.
542 const auto century_sec = 60 * 60 * 24 * 365 * int64_t{100};
543 const auto century = std::chrono::seconds(century_sec);
544 const auto chrono_future = MakeChronoUnixTime(century);
545 const auto chrono_past = MakeChronoUnixTime(-century);
546 EXPECT_EQ(absl::FromUnixSeconds(century_sec),
547 absl::FromChrono(chrono_future));
548 EXPECT_EQ(absl::FromUnixSeconds(-century_sec), absl::FromChrono(chrono_past));
549
550 // Roundtrip them both back to chrono.
551 EXPECT_EQ(chrono_future,
552 absl::ToChronoTime(absl::FromUnixSeconds(century_sec)));
553 EXPECT_EQ(chrono_past,
554 absl::ToChronoTime(absl::FromUnixSeconds(-century_sec)));
555 }
556
TEST(Time,ToChronoTime)557 TEST(Time, ToChronoTime) {
558 EXPECT_EQ(std::chrono::system_clock::from_time_t(-1),
559 absl::ToChronoTime(absl::FromTimeT(-1)));
560 EXPECT_EQ(std::chrono::system_clock::from_time_t(0),
561 absl::ToChronoTime(absl::FromTimeT(0)));
562 EXPECT_EQ(std::chrono::system_clock::from_time_t(1),
563 absl::ToChronoTime(absl::FromTimeT(1)));
564
565 EXPECT_EQ(MakeChronoUnixTime(std::chrono::milliseconds(-1)),
566 absl::ToChronoTime(absl::FromUnixMillis(-1)));
567 EXPECT_EQ(MakeChronoUnixTime(std::chrono::milliseconds(0)),
568 absl::ToChronoTime(absl::FromUnixMillis(0)));
569 EXPECT_EQ(MakeChronoUnixTime(std::chrono::milliseconds(1)),
570 absl::ToChronoTime(absl::FromUnixMillis(1)));
571
572 // Time before the Unix epoch should floor, not trunc.
573 const auto tick = absl::Nanoseconds(1) / 4;
574 EXPECT_EQ(std::chrono::system_clock::from_time_t(0) -
575 std::chrono::system_clock::duration(1),
576 absl::ToChronoTime(absl::UnixEpoch() - tick));
577 }
578
579 // Check that absl::int128 works as a std::chrono::duration representation.
TEST(Time,Chrono128)580 TEST(Time, Chrono128) {
581 // Define a std::chrono::time_point type whose time[sic]_since_epoch() is
582 // a signed 128-bit count of attoseconds. This has a range and resolution
583 // (currently) beyond those of absl::Time, and undoubtedly also beyond those
584 // of std::chrono::system_clock::time_point.
585 //
586 // Note: The to/from-chrono support should probably be updated to handle
587 // such wide representations.
588 using Timestamp =
589 std::chrono::time_point<std::chrono::system_clock,
590 std::chrono::duration<absl::int128, std::atto>>;
591
592 // Expect that we can round-trip the std::chrono::system_clock::time_point
593 // extremes through both absl::Time and Timestamp, and that Timestamp can
594 // handle the (current) absl::Time extremes.
595 //
596 // Note: We should use std::chrono::floor() instead of time_point_cast(),
597 // but floor() is only available since c++17.
598 for (const auto tp : {std::chrono::system_clock::time_point::min(),
599 std::chrono::system_clock::time_point::max()}) {
600 EXPECT_EQ(tp, absl::ToChronoTime(absl::FromChrono(tp)));
601 EXPECT_EQ(tp, std::chrono::time_point_cast<
602 std::chrono::system_clock::time_point::duration>(
603 std::chrono::time_point_cast<Timestamp::duration>(tp)));
604 }
605 Timestamp::duration::rep v = std::numeric_limits<int64_t>::min();
606 v *= Timestamp::duration::period::den;
607 auto ts = Timestamp(Timestamp::duration(v));
608 ts += std::chrono::duration<int64_t, std::atto>(0);
609 EXPECT_EQ(std::numeric_limits<int64_t>::min(),
610 ts.time_since_epoch().count() / Timestamp::duration::period::den);
611 EXPECT_EQ(0,
612 ts.time_since_epoch().count() % Timestamp::duration::period::den);
613 v = std::numeric_limits<int64_t>::max();
614 v *= Timestamp::duration::period::den;
615 ts = Timestamp(Timestamp::duration(v));
616 ts += std::chrono::duration<int64_t, std::atto>(999999999750000000);
617 EXPECT_EQ(std::numeric_limits<int64_t>::max(),
618 ts.time_since_epoch().count() / Timestamp::duration::period::den);
619 EXPECT_EQ(999999999750000000,
620 ts.time_since_epoch().count() % Timestamp::duration::period::den);
621 }
622
TEST(Time,TimeZoneAt)623 TEST(Time, TimeZoneAt) {
624 const absl::TimeZone nyc =
625 absl::time_internal::LoadTimeZone("America/New_York");
626 const std::string fmt = "%a, %e %b %Y %H:%M:%S %z (%Z)";
627
628 // A non-transition where the civil time is unique.
629 absl::CivilSecond nov01(2013, 11, 1, 8, 30, 0);
630 const auto nov01_ci = nyc.At(nov01);
631 EXPECT_EQ(absl::TimeZone::TimeInfo::UNIQUE, nov01_ci.kind);
632 EXPECT_EQ("Fri, 1 Nov 2013 08:30:00 -0400 (EDT)",
633 absl::FormatTime(fmt, nov01_ci.pre, nyc));
634 EXPECT_EQ(nov01_ci.pre, nov01_ci.trans);
635 EXPECT_EQ(nov01_ci.pre, nov01_ci.post);
636 EXPECT_EQ(nov01_ci.pre, absl::FromCivil(nov01, nyc));
637
638 // A Spring DST transition, when there is a gap in civil time
639 // and we prefer the later of the possible interpretations of a
640 // non-existent time.
641 absl::CivilSecond mar13(2011, 3, 13, 2, 15, 0);
642 const auto mar_ci = nyc.At(mar13);
643 EXPECT_EQ(absl::TimeZone::TimeInfo::SKIPPED, mar_ci.kind);
644 EXPECT_EQ("Sun, 13 Mar 2011 03:15:00 -0400 (EDT)",
645 absl::FormatTime(fmt, mar_ci.pre, nyc));
646 EXPECT_EQ("Sun, 13 Mar 2011 03:00:00 -0400 (EDT)",
647 absl::FormatTime(fmt, mar_ci.trans, nyc));
648 EXPECT_EQ("Sun, 13 Mar 2011 01:15:00 -0500 (EST)",
649 absl::FormatTime(fmt, mar_ci.post, nyc));
650 EXPECT_EQ(mar_ci.trans, absl::FromCivil(mar13, nyc));
651
652 // A Fall DST transition, when civil times are repeated and
653 // we prefer the earlier of the possible interpretations of an
654 // ambiguous time.
655 absl::CivilSecond nov06(2011, 11, 6, 1, 15, 0);
656 const auto nov06_ci = nyc.At(nov06);
657 EXPECT_EQ(absl::TimeZone::TimeInfo::REPEATED, nov06_ci.kind);
658 EXPECT_EQ("Sun, 6 Nov 2011 01:15:00 -0400 (EDT)",
659 absl::FormatTime(fmt, nov06_ci.pre, nyc));
660 EXPECT_EQ("Sun, 6 Nov 2011 01:00:00 -0500 (EST)",
661 absl::FormatTime(fmt, nov06_ci.trans, nyc));
662 EXPECT_EQ("Sun, 6 Nov 2011 01:15:00 -0500 (EST)",
663 absl::FormatTime(fmt, nov06_ci.post, nyc));
664 EXPECT_EQ(nov06_ci.pre, absl::FromCivil(nov06, nyc));
665
666 // Check that (time_t) -1 is handled correctly.
667 absl::CivilSecond minus1(1969, 12, 31, 18, 59, 59);
668 const auto minus1_cl = nyc.At(minus1);
669 EXPECT_EQ(absl::TimeZone::TimeInfo::UNIQUE, minus1_cl.kind);
670 EXPECT_EQ(-1, absl::ToTimeT(minus1_cl.pre));
671 EXPECT_EQ("Wed, 31 Dec 1969 18:59:59 -0500 (EST)",
672 absl::FormatTime(fmt, minus1_cl.pre, nyc));
673 EXPECT_EQ("Wed, 31 Dec 1969 23:59:59 +0000 (UTC)",
674 absl::FormatTime(fmt, minus1_cl.pre, absl::UTCTimeZone()));
675 }
676
677 // FromCivil(CivilSecond(year, mon, day, hour, min, sec), UTCTimeZone())
678 // has a specialized fastpath implementation, which we exercise here.
TEST(Time,FromCivilUTC)679 TEST(Time, FromCivilUTC) {
680 const absl::TimeZone utc = absl::UTCTimeZone();
681 const std::string fmt = "%a, %e %b %Y %H:%M:%S %z (%Z)";
682 const int kMax = std::numeric_limits<int>::max();
683 const int kMin = std::numeric_limits<int>::min();
684 absl::Time t;
685
686 // 292091940881 is the last positive year to use the fastpath.
687 t = absl::FromCivil(
688 absl::CivilSecond(292091940881, kMax, kMax, kMax, kMax, kMax), utc);
689 EXPECT_EQ("Fri, 25 Nov 292277026596 12:21:07 +0000 (UTC)",
690 absl::FormatTime(fmt, t, utc));
691 t = absl::FromCivil(
692 absl::CivilSecond(292091940882, kMax, kMax, kMax, kMax, kMax), utc);
693 EXPECT_EQ("infinite-future", absl::FormatTime(fmt, t, utc)); // no overflow
694
695 // -292091936940 is the last negative year to use the fastpath.
696 t = absl::FromCivil(
697 absl::CivilSecond(-292091936940, kMin, kMin, kMin, kMin, kMin), utc);
698 EXPECT_EQ("Fri, 1 Nov -292277022657 10:37:52 +0000 (UTC)",
699 absl::FormatTime(fmt, t, utc));
700 t = absl::FromCivil(
701 absl::CivilSecond(-292091936941, kMin, kMin, kMin, kMin, kMin), utc);
702 EXPECT_EQ("infinite-past", absl::FormatTime(fmt, t, utc)); // no underflow
703
704 // Check that we're counting leap years correctly.
705 t = absl::FromCivil(absl::CivilSecond(1900, 2, 28, 23, 59, 59), utc);
706 EXPECT_EQ("Wed, 28 Feb 1900 23:59:59 +0000 (UTC)",
707 absl::FormatTime(fmt, t, utc));
708 t = absl::FromCivil(absl::CivilSecond(1900, 3, 1, 0, 0, 0), utc);
709 EXPECT_EQ("Thu, 1 Mar 1900 00:00:00 +0000 (UTC)",
710 absl::FormatTime(fmt, t, utc));
711 t = absl::FromCivil(absl::CivilSecond(2000, 2, 29, 23, 59, 59), utc);
712 EXPECT_EQ("Tue, 29 Feb 2000 23:59:59 +0000 (UTC)",
713 absl::FormatTime(fmt, t, utc));
714 t = absl::FromCivil(absl::CivilSecond(2000, 3, 1, 0, 0, 0), utc);
715 EXPECT_EQ("Wed, 1 Mar 2000 00:00:00 +0000 (UTC)",
716 absl::FormatTime(fmt, t, utc));
717 }
718
TEST(Time,ToTM)719 TEST(Time, ToTM) {
720 const absl::TimeZone utc = absl::UTCTimeZone();
721
722 // Compares the results of ToTM() to gmtime_r() for lots of times over the
723 // course of a few days.
724 const absl::Time start =
725 absl::FromCivil(absl::CivilSecond(2014, 1, 2, 3, 4, 5), utc);
726 const absl::Time end =
727 absl::FromCivil(absl::CivilSecond(2014, 1, 5, 3, 4, 5), utc);
728 for (absl::Time t = start; t < end; t += absl::Seconds(30)) {
729 const struct tm tm_bt = ToTM(t, utc);
730 const time_t tt = absl::ToTimeT(t);
731 struct tm tm_lc;
732 #ifdef _WIN32
733 gmtime_s(&tm_lc, &tt);
734 #else
735 gmtime_r(&tt, &tm_lc);
736 #endif
737 EXPECT_EQ(tm_lc.tm_year, tm_bt.tm_year);
738 EXPECT_EQ(tm_lc.tm_mon, tm_bt.tm_mon);
739 EXPECT_EQ(tm_lc.tm_mday, tm_bt.tm_mday);
740 EXPECT_EQ(tm_lc.tm_hour, tm_bt.tm_hour);
741 EXPECT_EQ(tm_lc.tm_min, tm_bt.tm_min);
742 EXPECT_EQ(tm_lc.tm_sec, tm_bt.tm_sec);
743 EXPECT_EQ(tm_lc.tm_wday, tm_bt.tm_wday);
744 EXPECT_EQ(tm_lc.tm_yday, tm_bt.tm_yday);
745 EXPECT_EQ(tm_lc.tm_isdst, tm_bt.tm_isdst);
746
747 ASSERT_FALSE(HasFailure());
748 }
749
750 // Checks that the tm_isdst field is correct when in standard time.
751 const absl::TimeZone nyc =
752 absl::time_internal::LoadTimeZone("America/New_York");
753 absl::Time t = absl::FromCivil(absl::CivilSecond(2014, 3, 1, 0, 0, 0), nyc);
754 struct tm tm = ToTM(t, nyc);
755 EXPECT_FALSE(tm.tm_isdst);
756
757 // Checks that the tm_isdst field is correct when in daylight time.
758 t = absl::FromCivil(absl::CivilSecond(2014, 4, 1, 0, 0, 0), nyc);
759 tm = ToTM(t, nyc);
760 EXPECT_TRUE(tm.tm_isdst);
761
762 // Checks overflow.
763 tm = ToTM(absl::InfiniteFuture(), nyc);
764 EXPECT_EQ(std::numeric_limits<int>::max() - 1900, tm.tm_year);
765 EXPECT_EQ(11, tm.tm_mon);
766 EXPECT_EQ(31, tm.tm_mday);
767 EXPECT_EQ(23, tm.tm_hour);
768 EXPECT_EQ(59, tm.tm_min);
769 EXPECT_EQ(59, tm.tm_sec);
770 EXPECT_EQ(4, tm.tm_wday);
771 EXPECT_EQ(364, tm.tm_yday);
772 EXPECT_FALSE(tm.tm_isdst);
773
774 // Checks underflow.
775 tm = ToTM(absl::InfinitePast(), nyc);
776 EXPECT_EQ(std::numeric_limits<int>::min(), tm.tm_year);
777 EXPECT_EQ(0, tm.tm_mon);
778 EXPECT_EQ(1, tm.tm_mday);
779 EXPECT_EQ(0, tm.tm_hour);
780 EXPECT_EQ(0, tm.tm_min);
781 EXPECT_EQ(0, tm.tm_sec);
782 EXPECT_EQ(0, tm.tm_wday);
783 EXPECT_EQ(0, tm.tm_yday);
784 EXPECT_FALSE(tm.tm_isdst);
785 }
786
TEST(Time,FromTM)787 TEST(Time, FromTM) {
788 const absl::TimeZone nyc =
789 absl::time_internal::LoadTimeZone("America/New_York");
790
791 // Verifies that tm_isdst doesn't affect anything when the time is unique.
792 struct tm tm;
793 std::memset(&tm, 0, sizeof(tm));
794 tm.tm_year = 2014 - 1900;
795 tm.tm_mon = 6 - 1;
796 tm.tm_mday = 28;
797 tm.tm_hour = 1;
798 tm.tm_min = 2;
799 tm.tm_sec = 3;
800 tm.tm_isdst = -1;
801 absl::Time t = FromTM(tm, nyc);
802 EXPECT_EQ("2014-06-28T01:02:03-04:00", absl::FormatTime(t, nyc)); // DST
803 tm.tm_isdst = 0;
804 t = FromTM(tm, nyc);
805 EXPECT_EQ("2014-06-28T01:02:03-04:00", absl::FormatTime(t, nyc)); // DST
806 tm.tm_isdst = 1;
807 t = FromTM(tm, nyc);
808 EXPECT_EQ("2014-06-28T01:02:03-04:00", absl::FormatTime(t, nyc)); // DST
809
810 // Adjusts tm to refer to an ambiguous time.
811 tm.tm_year = 2014 - 1900;
812 tm.tm_mon = 11 - 1;
813 tm.tm_mday = 2;
814 tm.tm_hour = 1;
815 tm.tm_min = 30;
816 tm.tm_sec = 42;
817 tm.tm_isdst = -1;
818 t = FromTM(tm, nyc);
819 EXPECT_EQ("2014-11-02T01:30:42-04:00", absl::FormatTime(t, nyc)); // DST
820 tm.tm_isdst = 0;
821 t = FromTM(tm, nyc);
822 EXPECT_EQ("2014-11-02T01:30:42-05:00", absl::FormatTime(t, nyc)); // STD
823 tm.tm_isdst = 1;
824 t = FromTM(tm, nyc);
825 EXPECT_EQ("2014-11-02T01:30:42-04:00", absl::FormatTime(t, nyc)); // DST
826
827 // Adjusts tm to refer to a skipped time.
828 tm.tm_year = 2014 - 1900;
829 tm.tm_mon = 3 - 1;
830 tm.tm_mday = 9;
831 tm.tm_hour = 2;
832 tm.tm_min = 30;
833 tm.tm_sec = 42;
834 tm.tm_isdst = -1;
835 t = FromTM(tm, nyc);
836 EXPECT_EQ("2014-03-09T03:30:42-04:00", absl::FormatTime(t, nyc)); // DST
837 tm.tm_isdst = 0;
838 t = FromTM(tm, nyc);
839 EXPECT_EQ("2014-03-09T01:30:42-05:00", absl::FormatTime(t, nyc)); // STD
840 tm.tm_isdst = 1;
841 t = FromTM(tm, nyc);
842 EXPECT_EQ("2014-03-09T03:30:42-04:00", absl::FormatTime(t, nyc)); // DST
843
844 // Adjusts tm to refer to a time with a year larger than 2147483647.
845 tm.tm_year = 2147483647 - 1900 + 1;
846 tm.tm_mon = 6 - 1;
847 tm.tm_mday = 28;
848 tm.tm_hour = 1;
849 tm.tm_min = 2;
850 tm.tm_sec = 3;
851 tm.tm_isdst = -1;
852 t = FromTM(tm, absl::UTCTimeZone());
853 EXPECT_EQ("2147483648-06-28T01:02:03+00:00",
854 absl::FormatTime(t, absl::UTCTimeZone()));
855
856 // Adjusts tm to refer to a time with a very large month.
857 tm.tm_year = 2019 - 1900;
858 tm.tm_mon = 2147483647;
859 tm.tm_mday = 28;
860 tm.tm_hour = 1;
861 tm.tm_min = 2;
862 tm.tm_sec = 3;
863 tm.tm_isdst = -1;
864 t = FromTM(tm, absl::UTCTimeZone());
865 EXPECT_EQ("178958989-08-28T01:02:03+00:00",
866 absl::FormatTime(t, absl::UTCTimeZone()));
867 }
868
TEST(Time,TMRoundTrip)869 TEST(Time, TMRoundTrip) {
870 const absl::TimeZone nyc =
871 absl::time_internal::LoadTimeZone("America/New_York");
872
873 // Test round-tripping across a skipped transition
874 absl::Time start = absl::FromCivil(absl::CivilHour(2014, 3, 9, 0), nyc);
875 absl::Time end = absl::FromCivil(absl::CivilHour(2014, 3, 9, 4), nyc);
876 for (absl::Time t = start; t < end; t += absl::Minutes(1)) {
877 struct tm tm = ToTM(t, nyc);
878 absl::Time rt = FromTM(tm, nyc);
879 EXPECT_EQ(rt, t);
880 }
881
882 // Test round-tripping across an ambiguous transition
883 start = absl::FromCivil(absl::CivilHour(2014, 11, 2, 0), nyc);
884 end = absl::FromCivil(absl::CivilHour(2014, 11, 2, 4), nyc);
885 for (absl::Time t = start; t < end; t += absl::Minutes(1)) {
886 struct tm tm = ToTM(t, nyc);
887 absl::Time rt = FromTM(tm, nyc);
888 EXPECT_EQ(rt, t);
889 }
890
891 // Test round-tripping of unique instants crossing a day boundary
892 start = absl::FromCivil(absl::CivilHour(2014, 6, 27, 22), nyc);
893 end = absl::FromCivil(absl::CivilHour(2014, 6, 28, 4), nyc);
894 for (absl::Time t = start; t < end; t += absl::Minutes(1)) {
895 struct tm tm = ToTM(t, nyc);
896 absl::Time rt = FromTM(tm, nyc);
897 EXPECT_EQ(rt, t);
898 }
899 }
900
TEST(Time,Range)901 TEST(Time, Range) {
902 // The API's documented range is +/- 100 billion years.
903 const absl::Duration range = absl::Hours(24) * 365.2425 * 100000000000;
904
905 // Arithmetic and comparison still works at +/-range around base values.
906 absl::Time bases[2] = {absl::UnixEpoch(), absl::Now()};
907 for (const auto base : bases) {
908 absl::Time bottom = base - range;
909 EXPECT_GT(bottom, bottom - absl::Nanoseconds(1));
910 EXPECT_LT(bottom, bottom + absl::Nanoseconds(1));
911 absl::Time top = base + range;
912 EXPECT_GT(top, top - absl::Nanoseconds(1));
913 EXPECT_LT(top, top + absl::Nanoseconds(1));
914 absl::Duration full_range = 2 * range;
915 EXPECT_EQ(full_range, top - bottom);
916 EXPECT_EQ(-full_range, bottom - top);
917 }
918 }
919
TEST(Time,Limits)920 TEST(Time, Limits) {
921 // It is an implementation detail that Time().rep_ == ZeroDuration(),
922 // and that the resolution of a Duration is 1/4 of a nanosecond.
923 const absl::Time zero;
924 const absl::Time max =
925 zero + absl::Seconds(std::numeric_limits<int64_t>::max()) +
926 absl::Nanoseconds(999999999) + absl::Nanoseconds(3) / 4;
927 const absl::Time min =
928 zero + absl::Seconds(std::numeric_limits<int64_t>::min());
929
930 // Some simple max/min bounds checks.
931 EXPECT_LT(max, absl::InfiniteFuture());
932 EXPECT_GT(min, absl::InfinitePast());
933 EXPECT_LT(zero, max);
934 EXPECT_GT(zero, min);
935 EXPECT_GE(absl::UnixEpoch(), min);
936 EXPECT_LT(absl::UnixEpoch(), max);
937
938 // Check sign of Time differences.
939 EXPECT_LT(absl::ZeroDuration(), max - zero);
940 EXPECT_LT(absl::ZeroDuration(),
941 zero - absl::Nanoseconds(1) / 4 - min); // avoid zero - min
942
943 // Arithmetic works at max - 0.25ns and min + 0.25ns.
944 EXPECT_GT(max, max - absl::Nanoseconds(1) / 4);
945 EXPECT_LT(min, min + absl::Nanoseconds(1) / 4);
946 }
947
TEST(Time,ConversionSaturation)948 TEST(Time, ConversionSaturation) {
949 const absl::TimeZone utc = absl::UTCTimeZone();
950 absl::Time t;
951
952 const auto max_time_t = std::numeric_limits<time_t>::max();
953 const auto min_time_t = std::numeric_limits<time_t>::min();
954 time_t tt = max_time_t - 1;
955 t = absl::FromTimeT(tt);
956 tt = absl::ToTimeT(t);
957 EXPECT_EQ(max_time_t - 1, tt);
958 t += absl::Seconds(1);
959 tt = absl::ToTimeT(t);
960 EXPECT_EQ(max_time_t, tt);
961 t += absl::Seconds(1); // no effect
962 tt = absl::ToTimeT(t);
963 EXPECT_EQ(max_time_t, tt);
964
965 tt = min_time_t + 1;
966 t = absl::FromTimeT(tt);
967 tt = absl::ToTimeT(t);
968 EXPECT_EQ(min_time_t + 1, tt);
969 t -= absl::Seconds(1);
970 tt = absl::ToTimeT(t);
971 EXPECT_EQ(min_time_t, tt);
972 t -= absl::Seconds(1); // no effect
973 tt = absl::ToTimeT(t);
974 EXPECT_EQ(min_time_t, tt);
975
976 const auto max_timeval_sec =
977 std::numeric_limits<decltype(timeval::tv_sec)>::max();
978 const auto min_timeval_sec =
979 std::numeric_limits<decltype(timeval::tv_sec)>::min();
980 timeval tv;
981 tv.tv_sec = max_timeval_sec;
982 tv.tv_usec = 999998;
983 t = absl::TimeFromTimeval(tv);
984 tv = ToTimeval(t);
985 EXPECT_EQ(max_timeval_sec, tv.tv_sec);
986 EXPECT_EQ(999998, tv.tv_usec);
987 t += absl::Microseconds(1);
988 tv = ToTimeval(t);
989 EXPECT_EQ(max_timeval_sec, tv.tv_sec);
990 EXPECT_EQ(999999, tv.tv_usec);
991 t += absl::Microseconds(1); // no effect
992 tv = ToTimeval(t);
993 EXPECT_EQ(max_timeval_sec, tv.tv_sec);
994 EXPECT_EQ(999999, tv.tv_usec);
995
996 tv.tv_sec = min_timeval_sec;
997 tv.tv_usec = 1;
998 t = absl::TimeFromTimeval(tv);
999 tv = ToTimeval(t);
1000 EXPECT_EQ(min_timeval_sec, tv.tv_sec);
1001 EXPECT_EQ(1, tv.tv_usec);
1002 t -= absl::Microseconds(1);
1003 tv = ToTimeval(t);
1004 EXPECT_EQ(min_timeval_sec, tv.tv_sec);
1005 EXPECT_EQ(0, tv.tv_usec);
1006 t -= absl::Microseconds(1); // no effect
1007 tv = ToTimeval(t);
1008 EXPECT_EQ(min_timeval_sec, tv.tv_sec);
1009 EXPECT_EQ(0, tv.tv_usec);
1010
1011 const auto max_timespec_sec =
1012 std::numeric_limits<decltype(timespec::tv_sec)>::max();
1013 const auto min_timespec_sec =
1014 std::numeric_limits<decltype(timespec::tv_sec)>::min();
1015 timespec ts;
1016 ts.tv_sec = max_timespec_sec;
1017 ts.tv_nsec = 999999998;
1018 t = absl::TimeFromTimespec(ts);
1019 ts = absl::ToTimespec(t);
1020 EXPECT_EQ(max_timespec_sec, ts.tv_sec);
1021 EXPECT_EQ(999999998, ts.tv_nsec);
1022 t += absl::Nanoseconds(1);
1023 ts = absl::ToTimespec(t);
1024 EXPECT_EQ(max_timespec_sec, ts.tv_sec);
1025 EXPECT_EQ(999999999, ts.tv_nsec);
1026 t += absl::Nanoseconds(1); // no effect
1027 ts = absl::ToTimespec(t);
1028 EXPECT_EQ(max_timespec_sec, ts.tv_sec);
1029 EXPECT_EQ(999999999, ts.tv_nsec);
1030
1031 ts.tv_sec = min_timespec_sec;
1032 ts.tv_nsec = 1;
1033 t = absl::TimeFromTimespec(ts);
1034 ts = absl::ToTimespec(t);
1035 EXPECT_EQ(min_timespec_sec, ts.tv_sec);
1036 EXPECT_EQ(1, ts.tv_nsec);
1037 t -= absl::Nanoseconds(1);
1038 ts = absl::ToTimespec(t);
1039 EXPECT_EQ(min_timespec_sec, ts.tv_sec);
1040 EXPECT_EQ(0, ts.tv_nsec);
1041 t -= absl::Nanoseconds(1); // no effect
1042 ts = absl::ToTimespec(t);
1043 EXPECT_EQ(min_timespec_sec, ts.tv_sec);
1044 EXPECT_EQ(0, ts.tv_nsec);
1045
1046 // Checks how TimeZone::At() saturates on infinities.
1047 auto ci = utc.At(absl::InfiniteFuture());
1048 EXPECT_CIVIL_INFO(ci, std::numeric_limits<int64_t>::max(), 12, 31, 23,
1049 59, 59, 0, false);
1050 EXPECT_EQ(absl::InfiniteDuration(), ci.subsecond);
1051 EXPECT_EQ(absl::Weekday::thursday, absl::GetWeekday(ci.cs));
1052 EXPECT_EQ(365, absl::GetYearDay(ci.cs));
1053 EXPECT_STREQ("-00", ci.zone_abbr); // artifact of TimeZone::At()
1054 ci = utc.At(absl::InfinitePast());
1055 EXPECT_CIVIL_INFO(ci, std::numeric_limits<int64_t>::min(), 1, 1, 0, 0,
1056 0, 0, false);
1057 EXPECT_EQ(-absl::InfiniteDuration(), ci.subsecond);
1058 EXPECT_EQ(absl::Weekday::sunday, absl::GetWeekday(ci.cs));
1059 EXPECT_EQ(1, absl::GetYearDay(ci.cs));
1060 EXPECT_STREQ("-00", ci.zone_abbr); // artifact of TimeZone::At()
1061
1062 // Approach the maximal Time value from below.
1063 t = absl::FromCivil(absl::CivilSecond(292277026596, 12, 4, 15, 30, 6), utc);
1064 EXPECT_EQ("292277026596-12-04T15:30:06+00:00",
1065 absl::FormatTime(absl::RFC3339_full, t, utc));
1066 t = absl::FromCivil(absl::CivilSecond(292277026596, 12, 4, 15, 30, 7), utc);
1067 EXPECT_EQ("292277026596-12-04T15:30:07+00:00",
1068 absl::FormatTime(absl::RFC3339_full, t, utc));
1069 EXPECT_EQ(
1070 absl::UnixEpoch() + absl::Seconds(std::numeric_limits<int64_t>::max()), t);
1071
1072 // Checks that we can also get the maximal Time value for a far-east zone.
1073 const absl::TimeZone plus14 = absl::FixedTimeZone(14 * 60 * 60);
1074 t = absl::FromCivil(absl::CivilSecond(292277026596, 12, 5, 5, 30, 7), plus14);
1075 EXPECT_EQ("292277026596-12-05T05:30:07+14:00",
1076 absl::FormatTime(absl::RFC3339_full, t, plus14));
1077 EXPECT_EQ(
1078 absl::UnixEpoch() + absl::Seconds(std::numeric_limits<int64_t>::max()), t);
1079
1080 // One second later should push us to infinity.
1081 t = absl::FromCivil(absl::CivilSecond(292277026596, 12, 4, 15, 30, 8), utc);
1082 EXPECT_EQ("infinite-future", absl::FormatTime(absl::RFC3339_full, t, utc));
1083
1084 // Approach the minimal Time value from above.
1085 t = absl::FromCivil(absl::CivilSecond(-292277022657, 1, 27, 8, 29, 53), utc);
1086 EXPECT_EQ("-292277022657-01-27T08:29:53+00:00",
1087 absl::FormatTime(absl::RFC3339_full, t, utc));
1088 t = absl::FromCivil(absl::CivilSecond(-292277022657, 1, 27, 8, 29, 52), utc);
1089 EXPECT_EQ("-292277022657-01-27T08:29:52+00:00",
1090 absl::FormatTime(absl::RFC3339_full, t, utc));
1091 EXPECT_EQ(
1092 absl::UnixEpoch() + absl::Seconds(std::numeric_limits<int64_t>::min()), t);
1093
1094 // Checks that we can also get the minimal Time value for a far-west zone.
1095 const absl::TimeZone minus12 = absl::FixedTimeZone(-12 * 60 * 60);
1096 t = absl::FromCivil(absl::CivilSecond(-292277022657, 1, 26, 20, 29, 52),
1097 minus12);
1098 EXPECT_EQ("-292277022657-01-26T20:29:52-12:00",
1099 absl::FormatTime(absl::RFC3339_full, t, minus12));
1100 EXPECT_EQ(
1101 absl::UnixEpoch() + absl::Seconds(std::numeric_limits<int64_t>::min()), t);
1102
1103 // One second before should push us to -infinity.
1104 t = absl::FromCivil(absl::CivilSecond(-292277022657, 1, 27, 8, 29, 51), utc);
1105 EXPECT_EQ("infinite-past", absl::FormatTime(absl::RFC3339_full, t, utc));
1106 }
1107
1108 // In zones with POSIX-style recurring rules we use special logic to
1109 // handle conversions in the distant future. Here we check the limits
1110 // of those conversions, particularly with respect to integer overflow.
TEST(Time,ExtendedConversionSaturation)1111 TEST(Time, ExtendedConversionSaturation) {
1112 const absl::TimeZone syd =
1113 absl::time_internal::LoadTimeZone("Australia/Sydney");
1114 const absl::TimeZone nyc =
1115 absl::time_internal::LoadTimeZone("America/New_York");
1116 const absl::Time max =
1117 absl::FromUnixSeconds(std::numeric_limits<int64_t>::max());
1118 absl::TimeZone::CivilInfo ci;
1119 absl::Time t;
1120
1121 // The maximal time converted in each zone.
1122 ci = syd.At(max);
1123 EXPECT_CIVIL_INFO(ci, 292277026596, 12, 5, 2, 30, 7, 39600, true);
1124 t = absl::FromCivil(absl::CivilSecond(292277026596, 12, 5, 2, 30, 7), syd);
1125 EXPECT_EQ(max, t);
1126 ci = nyc.At(max);
1127 EXPECT_CIVIL_INFO(ci, 292277026596, 12, 4, 10, 30, 7, -18000, false);
1128 t = absl::FromCivil(absl::CivilSecond(292277026596, 12, 4, 10, 30, 7), nyc);
1129 EXPECT_EQ(max, t);
1130
1131 // One second later should push us to infinity.
1132 t = absl::FromCivil(absl::CivilSecond(292277026596, 12, 5, 2, 30, 8), syd);
1133 EXPECT_EQ(absl::InfiniteFuture(), t);
1134 t = absl::FromCivil(absl::CivilSecond(292277026596, 12, 4, 10, 30, 8), nyc);
1135 EXPECT_EQ(absl::InfiniteFuture(), t);
1136
1137 // And we should stick there.
1138 t = absl::FromCivil(absl::CivilSecond(292277026596, 12, 5, 2, 30, 9), syd);
1139 EXPECT_EQ(absl::InfiniteFuture(), t);
1140 t = absl::FromCivil(absl::CivilSecond(292277026596, 12, 4, 10, 30, 9), nyc);
1141 EXPECT_EQ(absl::InfiniteFuture(), t);
1142
1143 // All the way up to a saturated date/time, without overflow.
1144 t = absl::FromCivil(absl::CivilSecond::max(), syd);
1145 EXPECT_EQ(absl::InfiniteFuture(), t);
1146 t = absl::FromCivil(absl::CivilSecond::max(), nyc);
1147 EXPECT_EQ(absl::InfiniteFuture(), t);
1148 }
1149
TEST(Time,FromCivilAlignment)1150 TEST(Time, FromCivilAlignment) {
1151 const absl::TimeZone utc = absl::UTCTimeZone();
1152 const absl::CivilSecond cs(2015, 2, 3, 4, 5, 6);
1153 absl::Time t = absl::FromCivil(cs, utc);
1154 EXPECT_EQ("2015-02-03T04:05:06+00:00", absl::FormatTime(t, utc));
1155 t = absl::FromCivil(absl::CivilMinute(cs), utc);
1156 EXPECT_EQ("2015-02-03T04:05:00+00:00", absl::FormatTime(t, utc));
1157 t = absl::FromCivil(absl::CivilHour(cs), utc);
1158 EXPECT_EQ("2015-02-03T04:00:00+00:00", absl::FormatTime(t, utc));
1159 t = absl::FromCivil(absl::CivilDay(cs), utc);
1160 EXPECT_EQ("2015-02-03T00:00:00+00:00", absl::FormatTime(t, utc));
1161 t = absl::FromCivil(absl::CivilMonth(cs), utc);
1162 EXPECT_EQ("2015-02-01T00:00:00+00:00", absl::FormatTime(t, utc));
1163 t = absl::FromCivil(absl::CivilYear(cs), utc);
1164 EXPECT_EQ("2015-01-01T00:00:00+00:00", absl::FormatTime(t, utc));
1165 }
1166
TEST(Time,LegacyDateTime)1167 TEST(Time, LegacyDateTime) {
1168 const absl::TimeZone utc = absl::UTCTimeZone();
1169 const std::string ymdhms = "%Y-%m-%d %H:%M:%S";
1170 const int kMax = std::numeric_limits<int>::max();
1171 const int kMin = std::numeric_limits<int>::min();
1172 absl::Time t;
1173
1174 t = absl::FromDateTime(std::numeric_limits<absl::civil_year_t>::max(),
1175 kMax, kMax, kMax, kMax, kMax, utc);
1176 EXPECT_EQ("infinite-future",
1177 absl::FormatTime(ymdhms, t, utc)); // no overflow
1178 t = absl::FromDateTime(std::numeric_limits<absl::civil_year_t>::min(),
1179 kMin, kMin, kMin, kMin, kMin, utc);
1180 EXPECT_EQ("infinite-past",
1181 absl::FormatTime(ymdhms, t, utc)); // no overflow
1182
1183 // Check normalization.
1184 EXPECT_TRUE(absl::ConvertDateTime(2013, 10, 32, 8, 30, 0, utc).normalized);
1185 t = absl::FromDateTime(2015, 1, 1, 0, 0, 60, utc);
1186 EXPECT_EQ("2015-01-01 00:01:00", absl::FormatTime(ymdhms, t, utc));
1187 t = absl::FromDateTime(2015, 1, 1, 0, 60, 0, utc);
1188 EXPECT_EQ("2015-01-01 01:00:00", absl::FormatTime(ymdhms, t, utc));
1189 t = absl::FromDateTime(2015, 1, 1, 24, 0, 0, utc);
1190 EXPECT_EQ("2015-01-02 00:00:00", absl::FormatTime(ymdhms, t, utc));
1191 t = absl::FromDateTime(2015, 1, 32, 0, 0, 0, utc);
1192 EXPECT_EQ("2015-02-01 00:00:00", absl::FormatTime(ymdhms, t, utc));
1193 t = absl::FromDateTime(2015, 13, 1, 0, 0, 0, utc);
1194 EXPECT_EQ("2016-01-01 00:00:00", absl::FormatTime(ymdhms, t, utc));
1195 t = absl::FromDateTime(2015, 13, 32, 60, 60, 60, utc);
1196 EXPECT_EQ("2016-02-03 13:01:00", absl::FormatTime(ymdhms, t, utc));
1197 t = absl::FromDateTime(2015, 1, 1, 0, 0, -1, utc);
1198 EXPECT_EQ("2014-12-31 23:59:59", absl::FormatTime(ymdhms, t, utc));
1199 t = absl::FromDateTime(2015, 1, 1, 0, -1, 0, utc);
1200 EXPECT_EQ("2014-12-31 23:59:00", absl::FormatTime(ymdhms, t, utc));
1201 t = absl::FromDateTime(2015, 1, 1, -1, 0, 0, utc);
1202 EXPECT_EQ("2014-12-31 23:00:00", absl::FormatTime(ymdhms, t, utc));
1203 t = absl::FromDateTime(2015, 1, -1, 0, 0, 0, utc);
1204 EXPECT_EQ("2014-12-30 00:00:00", absl::FormatTime(ymdhms, t, utc));
1205 t = absl::FromDateTime(2015, -1, 1, 0, 0, 0, utc);
1206 EXPECT_EQ("2014-11-01 00:00:00", absl::FormatTime(ymdhms, t, utc));
1207 t = absl::FromDateTime(2015, -1, -1, -1, -1, -1, utc);
1208 EXPECT_EQ("2014-10-29 22:58:59", absl::FormatTime(ymdhms, t, utc));
1209 }
1210
TEST(Time,NextTransitionUTC)1211 TEST(Time, NextTransitionUTC) {
1212 const auto tz = absl::UTCTimeZone();
1213 absl::TimeZone::CivilTransition trans;
1214
1215 auto t = absl::InfinitePast();
1216 EXPECT_FALSE(tz.NextTransition(t, &trans));
1217
1218 t = absl::InfiniteFuture();
1219 EXPECT_FALSE(tz.NextTransition(t, &trans));
1220 }
1221
TEST(Time,PrevTransitionUTC)1222 TEST(Time, PrevTransitionUTC) {
1223 const auto tz = absl::UTCTimeZone();
1224 absl::TimeZone::CivilTransition trans;
1225
1226 auto t = absl::InfiniteFuture();
1227 EXPECT_FALSE(tz.PrevTransition(t, &trans));
1228
1229 t = absl::InfinitePast();
1230 EXPECT_FALSE(tz.PrevTransition(t, &trans));
1231 }
1232
TEST(Time,NextTransitionNYC)1233 TEST(Time, NextTransitionNYC) {
1234 const auto tz = absl::time_internal::LoadTimeZone("America/New_York");
1235 absl::TimeZone::CivilTransition trans;
1236
1237 auto t = absl::FromCivil(absl::CivilSecond(2018, 6, 30, 0, 0, 0), tz);
1238 EXPECT_TRUE(tz.NextTransition(t, &trans));
1239 EXPECT_EQ(absl::CivilSecond(2018, 11, 4, 2, 0, 0), trans.from);
1240 EXPECT_EQ(absl::CivilSecond(2018, 11, 4, 1, 0, 0), trans.to);
1241
1242 t = absl::InfiniteFuture();
1243 EXPECT_FALSE(tz.NextTransition(t, &trans));
1244
1245 t = absl::InfinitePast();
1246 EXPECT_TRUE(tz.NextTransition(t, &trans));
1247 if (trans.from == absl::CivilSecond(1918, 03, 31, 2, 0, 0)) {
1248 // It looks like the tzdata is only 32 bit (probably macOS),
1249 // which bottoms out at 1901-12-13T20:45:52+00:00.
1250 EXPECT_EQ(absl::CivilSecond(1918, 3, 31, 3, 0, 0), trans.to);
1251 } else {
1252 EXPECT_EQ(absl::CivilSecond(1883, 11, 18, 12, 3, 58), trans.from);
1253 EXPECT_EQ(absl::CivilSecond(1883, 11, 18, 12, 0, 0), trans.to);
1254 }
1255 }
1256
TEST(Time,PrevTransitionNYC)1257 TEST(Time, PrevTransitionNYC) {
1258 const auto tz = absl::time_internal::LoadTimeZone("America/New_York");
1259 absl::TimeZone::CivilTransition trans;
1260
1261 auto t = absl::FromCivil(absl::CivilSecond(2018, 6, 30, 0, 0, 0), tz);
1262 EXPECT_TRUE(tz.PrevTransition(t, &trans));
1263 EXPECT_EQ(absl::CivilSecond(2018, 3, 11, 2, 0, 0), trans.from);
1264 EXPECT_EQ(absl::CivilSecond(2018, 3, 11, 3, 0, 0), trans.to);
1265
1266 t = absl::InfinitePast();
1267 EXPECT_FALSE(tz.PrevTransition(t, &trans));
1268
1269 t = absl::InfiniteFuture();
1270 EXPECT_TRUE(tz.PrevTransition(t, &trans));
1271 // We have a transition but we don't know which one.
1272 }
1273
1274 } // namespace
1275