1 // Copyright 2018 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/civil_time.h"
16
17 #include <iomanip>
18 #include <limits>
19 #include <sstream>
20 #include <type_traits>
21
22 #include "gtest/gtest.h"
23 #include "absl/base/macros.h"
24 #include "absl/strings/str_format.h"
25
26 namespace {
27
TEST(CivilTime,DefaultConstruction)28 TEST(CivilTime, DefaultConstruction) {
29 absl::CivilSecond ss;
30 EXPECT_EQ("1970-01-01T00:00:00", absl::FormatCivilTime(ss));
31
32 absl::CivilMinute mm;
33 EXPECT_EQ("1970-01-01T00:00", absl::FormatCivilTime(mm));
34
35 absl::CivilHour hh;
36 EXPECT_EQ("1970-01-01T00", absl::FormatCivilTime(hh));
37
38 absl::CivilDay d;
39 EXPECT_EQ("1970-01-01", absl::FormatCivilTime(d));
40
41 absl::CivilMonth m;
42 EXPECT_EQ("1970-01", absl::FormatCivilTime(m));
43
44 absl::CivilYear y;
45 EXPECT_EQ("1970", absl::FormatCivilTime(y));
46 }
47
TEST(CivilTime,StructMember)48 TEST(CivilTime, StructMember) {
49 struct S {
50 absl::CivilDay day;
51 };
52 S s = {};
53 EXPECT_EQ(absl::CivilDay{}, s.day);
54 }
55
TEST(CivilTime,FieldsConstruction)56 TEST(CivilTime, FieldsConstruction) {
57 EXPECT_EQ("2015-01-02T03:04:05",
58 absl::FormatCivilTime(absl::CivilSecond(2015, 1, 2, 3, 4, 5)));
59 EXPECT_EQ("2015-01-02T03:04:00",
60 absl::FormatCivilTime(absl::CivilSecond(2015, 1, 2, 3, 4)));
61 EXPECT_EQ("2015-01-02T03:00:00",
62 absl::FormatCivilTime(absl::CivilSecond(2015, 1, 2, 3)));
63 EXPECT_EQ("2015-01-02T00:00:00",
64 absl::FormatCivilTime(absl::CivilSecond(2015, 1, 2)));
65 EXPECT_EQ("2015-01-01T00:00:00",
66 absl::FormatCivilTime(absl::CivilSecond(2015, 1)));
67 EXPECT_EQ("2015-01-01T00:00:00",
68 absl::FormatCivilTime(absl::CivilSecond(2015)));
69
70 EXPECT_EQ("2015-01-02T03:04",
71 absl::FormatCivilTime(absl::CivilMinute(2015, 1, 2, 3, 4, 5)));
72 EXPECT_EQ("2015-01-02T03:04",
73 absl::FormatCivilTime(absl::CivilMinute(2015, 1, 2, 3, 4)));
74 EXPECT_EQ("2015-01-02T03:00",
75 absl::FormatCivilTime(absl::CivilMinute(2015, 1, 2, 3)));
76 EXPECT_EQ("2015-01-02T00:00",
77 absl::FormatCivilTime(absl::CivilMinute(2015, 1, 2)));
78 EXPECT_EQ("2015-01-01T00:00",
79 absl::FormatCivilTime(absl::CivilMinute(2015, 1)));
80 EXPECT_EQ("2015-01-01T00:00",
81 absl::FormatCivilTime(absl::CivilMinute(2015)));
82
83 EXPECT_EQ("2015-01-02T03",
84 absl::FormatCivilTime(absl::CivilHour(2015, 1, 2, 3, 4, 5)));
85 EXPECT_EQ("2015-01-02T03",
86 absl::FormatCivilTime(absl::CivilHour(2015, 1, 2, 3, 4)));
87 EXPECT_EQ("2015-01-02T03",
88 absl::FormatCivilTime(absl::CivilHour(2015, 1, 2, 3)));
89 EXPECT_EQ("2015-01-02T00",
90 absl::FormatCivilTime(absl::CivilHour(2015, 1, 2)));
91 EXPECT_EQ("2015-01-01T00",
92 absl::FormatCivilTime(absl::CivilHour(2015, 1)));
93 EXPECT_EQ("2015-01-01T00",
94 absl::FormatCivilTime(absl::CivilHour(2015)));
95
96 EXPECT_EQ("2015-01-02",
97 absl::FormatCivilTime(absl::CivilDay(2015, 1, 2, 3, 4, 5)));
98 EXPECT_EQ("2015-01-02",
99 absl::FormatCivilTime(absl::CivilDay(2015, 1, 2, 3, 4)));
100 EXPECT_EQ("2015-01-02",
101 absl::FormatCivilTime(absl::CivilDay(2015, 1, 2, 3)));
102 EXPECT_EQ("2015-01-02",
103 absl::FormatCivilTime(absl::CivilDay(2015, 1, 2)));
104 EXPECT_EQ("2015-01-01",
105 absl::FormatCivilTime(absl::CivilDay(2015, 1)));
106 EXPECT_EQ("2015-01-01",
107 absl::FormatCivilTime(absl::CivilDay(2015)));
108
109 EXPECT_EQ("2015-01",
110 absl::FormatCivilTime(absl::CivilMonth(2015, 1, 2, 3, 4, 5)));
111 EXPECT_EQ("2015-01",
112 absl::FormatCivilTime(absl::CivilMonth(2015, 1, 2, 3, 4)));
113 EXPECT_EQ("2015-01",
114 absl::FormatCivilTime(absl::CivilMonth(2015, 1, 2, 3)));
115 EXPECT_EQ("2015-01",
116 absl::FormatCivilTime(absl::CivilMonth(2015, 1, 2)));
117 EXPECT_EQ("2015-01",
118 absl::FormatCivilTime(absl::CivilMonth(2015, 1)));
119 EXPECT_EQ("2015-01",
120 absl::FormatCivilTime(absl::CivilMonth(2015)));
121
122 EXPECT_EQ("2015",
123 absl::FormatCivilTime(absl::CivilYear(2015, 1, 2, 3, 4, 5)));
124 EXPECT_EQ("2015",
125 absl::FormatCivilTime(absl::CivilYear(2015, 1, 2, 3, 4)));
126 EXPECT_EQ("2015",
127 absl::FormatCivilTime(absl::CivilYear(2015, 1, 2, 3)));
128 EXPECT_EQ("2015",
129 absl::FormatCivilTime(absl::CivilYear(2015, 1, 2)));
130 EXPECT_EQ("2015",
131 absl::FormatCivilTime(absl::CivilYear(2015, 1)));
132 EXPECT_EQ("2015",
133 absl::FormatCivilTime(absl::CivilYear(2015)));
134 }
135
TEST(CivilTime,FieldsConstructionLimits)136 TEST(CivilTime, FieldsConstructionLimits) {
137 const int kIntMax = std::numeric_limits<int>::max();
138 EXPECT_EQ("2038-01-19T03:14:07",
139 absl::FormatCivilTime(absl::CivilSecond(
140 1970, 1, 1, 0, 0, kIntMax)));
141 EXPECT_EQ("6121-02-11T05:21:07",
142 absl::FormatCivilTime(absl::CivilSecond(
143 1970, 1, 1, 0, kIntMax, kIntMax)));
144 EXPECT_EQ("251104-11-20T12:21:07",
145 absl::FormatCivilTime(absl::CivilSecond(
146 1970, 1, 1, kIntMax, kIntMax, kIntMax)));
147 EXPECT_EQ("6130715-05-30T12:21:07",
148 absl::FormatCivilTime(absl::CivilSecond(
149 1970, 1, kIntMax, kIntMax, kIntMax, kIntMax)));
150 EXPECT_EQ("185087685-11-26T12:21:07",
151 absl::FormatCivilTime(absl::CivilSecond(
152 1970, kIntMax, kIntMax, kIntMax, kIntMax, kIntMax)));
153
154 const int kIntMin = std::numeric_limits<int>::min();
155 EXPECT_EQ("1901-12-13T20:45:52",
156 absl::FormatCivilTime(absl::CivilSecond(
157 1970, 1, 1, 0, 0, kIntMin)));
158 EXPECT_EQ("-2182-11-20T18:37:52",
159 absl::FormatCivilTime(absl::CivilSecond(
160 1970, 1, 1, 0, kIntMin, kIntMin)));
161 EXPECT_EQ("-247165-02-11T10:37:52",
162 absl::FormatCivilTime(absl::CivilSecond(
163 1970, 1, 1, kIntMin, kIntMin, kIntMin)));
164 EXPECT_EQ("-6126776-08-01T10:37:52",
165 absl::FormatCivilTime(absl::CivilSecond(
166 1970, 1, kIntMin, kIntMin, kIntMin, kIntMin)));
167 EXPECT_EQ("-185083747-10-31T10:37:52",
168 absl::FormatCivilTime(absl::CivilSecond(
169 1970, kIntMin, kIntMin, kIntMin, kIntMin, kIntMin)));
170 }
171
TEST(CivilTime,RangeLimits)172 TEST(CivilTime, RangeLimits) {
173 const absl::civil_year_t kYearMax =
174 std::numeric_limits<absl::civil_year_t>::max();
175 EXPECT_EQ(absl::CivilYear(kYearMax),
176 absl::CivilYear::max());
177 EXPECT_EQ(absl::CivilMonth(kYearMax, 12),
178 absl::CivilMonth::max());
179 EXPECT_EQ(absl::CivilDay(kYearMax, 12, 31),
180 absl::CivilDay::max());
181 EXPECT_EQ(absl::CivilHour(kYearMax, 12, 31, 23),
182 absl::CivilHour::max());
183 EXPECT_EQ(absl::CivilMinute(kYearMax, 12, 31, 23, 59),
184 absl::CivilMinute::max());
185 EXPECT_EQ(absl::CivilSecond(kYearMax, 12, 31, 23, 59, 59),
186 absl::CivilSecond::max());
187
188 const absl::civil_year_t kYearMin =
189 std::numeric_limits<absl::civil_year_t>::min();
190 EXPECT_EQ(absl::CivilYear(kYearMin),
191 absl::CivilYear::min());
192 EXPECT_EQ(absl::CivilMonth(kYearMin, 1),
193 absl::CivilMonth::min());
194 EXPECT_EQ(absl::CivilDay(kYearMin, 1, 1),
195 absl::CivilDay::min());
196 EXPECT_EQ(absl::CivilHour(kYearMin, 1, 1, 0),
197 absl::CivilHour::min());
198 EXPECT_EQ(absl::CivilMinute(kYearMin, 1, 1, 0, 0),
199 absl::CivilMinute::min());
200 EXPECT_EQ(absl::CivilSecond(kYearMin, 1, 1, 0, 0, 0),
201 absl::CivilSecond::min());
202 }
203
TEST(CivilTime,ImplicitCrossAlignment)204 TEST(CivilTime, ImplicitCrossAlignment) {
205 absl::CivilYear year(2015);
206 absl::CivilMonth month = year;
207 absl::CivilDay day = month;
208 absl::CivilHour hour = day;
209 absl::CivilMinute minute = hour;
210 absl::CivilSecond second = minute;
211
212 second = year;
213 EXPECT_EQ(second, year);
214 second = month;
215 EXPECT_EQ(second, month);
216 second = day;
217 EXPECT_EQ(second, day);
218 second = hour;
219 EXPECT_EQ(second, hour);
220 second = minute;
221 EXPECT_EQ(second, minute);
222
223 minute = year;
224 EXPECT_EQ(minute, year);
225 minute = month;
226 EXPECT_EQ(minute, month);
227 minute = day;
228 EXPECT_EQ(minute, day);
229 minute = hour;
230 EXPECT_EQ(minute, hour);
231
232 hour = year;
233 EXPECT_EQ(hour, year);
234 hour = month;
235 EXPECT_EQ(hour, month);
236 hour = day;
237 EXPECT_EQ(hour, day);
238
239 day = year;
240 EXPECT_EQ(day, year);
241 day = month;
242 EXPECT_EQ(day, month);
243
244 month = year;
245 EXPECT_EQ(month, year);
246
247 // Ensures unsafe conversions are not allowed.
248 EXPECT_FALSE(
249 (std::is_convertible<absl::CivilSecond, absl::CivilMinute>::value));
250 EXPECT_FALSE(
251 (std::is_convertible<absl::CivilSecond, absl::CivilHour>::value));
252 EXPECT_FALSE(
253 (std::is_convertible<absl::CivilSecond, absl::CivilDay>::value));
254 EXPECT_FALSE(
255 (std::is_convertible<absl::CivilSecond, absl::CivilMonth>::value));
256 EXPECT_FALSE(
257 (std::is_convertible<absl::CivilSecond, absl::CivilYear>::value));
258
259 EXPECT_FALSE(
260 (std::is_convertible<absl::CivilMinute, absl::CivilHour>::value));
261 EXPECT_FALSE(
262 (std::is_convertible<absl::CivilMinute, absl::CivilDay>::value));
263 EXPECT_FALSE(
264 (std::is_convertible<absl::CivilMinute, absl::CivilMonth>::value));
265 EXPECT_FALSE(
266 (std::is_convertible<absl::CivilMinute, absl::CivilYear>::value));
267
268 EXPECT_FALSE(
269 (std::is_convertible<absl::CivilHour, absl::CivilDay>::value));
270 EXPECT_FALSE(
271 (std::is_convertible<absl::CivilHour, absl::CivilMonth>::value));
272 EXPECT_FALSE(
273 (std::is_convertible<absl::CivilHour, absl::CivilYear>::value));
274
275 EXPECT_FALSE(
276 (std::is_convertible<absl::CivilDay, absl::CivilMonth>::value));
277 EXPECT_FALSE(
278 (std::is_convertible<absl::CivilDay, absl::CivilYear>::value));
279
280 EXPECT_FALSE(
281 (std::is_convertible<absl::CivilMonth, absl::CivilYear>::value));
282 }
283
TEST(CivilTime,ExplicitCrossAlignment)284 TEST(CivilTime, ExplicitCrossAlignment) {
285 //
286 // Assign from smaller units -> larger units
287 //
288
289 absl::CivilSecond second(2015, 1, 2, 3, 4, 5);
290 EXPECT_EQ("2015-01-02T03:04:05", absl::FormatCivilTime(second));
291
292 absl::CivilMinute minute(second);
293 EXPECT_EQ("2015-01-02T03:04", absl::FormatCivilTime(minute));
294
295 absl::CivilHour hour(minute);
296 EXPECT_EQ("2015-01-02T03", absl::FormatCivilTime(hour));
297
298 absl::CivilDay day(hour);
299 EXPECT_EQ("2015-01-02", absl::FormatCivilTime(day));
300
301 absl::CivilMonth month(day);
302 EXPECT_EQ("2015-01", absl::FormatCivilTime(month));
303
304 absl::CivilYear year(month);
305 EXPECT_EQ("2015", absl::FormatCivilTime(year));
306
307 //
308 // Now assign from larger units -> smaller units
309 //
310
311 month = absl::CivilMonth(year);
312 EXPECT_EQ("2015-01", absl::FormatCivilTime(month));
313
314 day = absl::CivilDay(month);
315 EXPECT_EQ("2015-01-01", absl::FormatCivilTime(day));
316
317 hour = absl::CivilHour(day);
318 EXPECT_EQ("2015-01-01T00", absl::FormatCivilTime(hour));
319
320 minute = absl::CivilMinute(hour);
321 EXPECT_EQ("2015-01-01T00:00", absl::FormatCivilTime(minute));
322
323 second = absl::CivilSecond(minute);
324 EXPECT_EQ("2015-01-01T00:00:00", absl::FormatCivilTime(second));
325 }
326
327 // Metafunction to test whether difference is allowed between two types.
328 template <typename T1, typename T2>
329 struct HasDiff {
330 template <typename U1, typename U2>
331 static std::false_type test(...);
332 template <typename U1, typename U2>
333 static std::true_type test(decltype(std::declval<U1>() - std::declval<U2>()));
334 static constexpr bool value = decltype(test<T1, T2>(0))::value;
335 };
336
TEST(CivilTime,DisallowCrossAlignedDifference)337 TEST(CivilTime, DisallowCrossAlignedDifference) {
338 // Difference is allowed between types with the same alignment.
339 static_assert(HasDiff<absl::CivilSecond, absl::CivilSecond>::value, "");
340 static_assert(HasDiff<absl::CivilMinute, absl::CivilMinute>::value, "");
341 static_assert(HasDiff<absl::CivilHour, absl::CivilHour>::value, "");
342 static_assert(HasDiff<absl::CivilDay, absl::CivilDay>::value, "");
343 static_assert(HasDiff<absl::CivilMonth, absl::CivilMonth>::value, "");
344 static_assert(HasDiff<absl::CivilYear, absl::CivilYear>::value, "");
345
346 // Difference is disallowed between types with different alignments.
347 static_assert(!HasDiff<absl::CivilSecond, absl::CivilMinute>::value, "");
348 static_assert(!HasDiff<absl::CivilSecond, absl::CivilHour>::value, "");
349 static_assert(!HasDiff<absl::CivilSecond, absl::CivilDay>::value, "");
350 static_assert(!HasDiff<absl::CivilSecond, absl::CivilMonth>::value, "");
351 static_assert(!HasDiff<absl::CivilSecond, absl::CivilYear>::value, "");
352
353 static_assert(!HasDiff<absl::CivilMinute, absl::CivilHour>::value, "");
354 static_assert(!HasDiff<absl::CivilMinute, absl::CivilDay>::value, "");
355 static_assert(!HasDiff<absl::CivilMinute, absl::CivilMonth>::value, "");
356 static_assert(!HasDiff<absl::CivilMinute, absl::CivilYear>::value, "");
357
358 static_assert(!HasDiff<absl::CivilHour, absl::CivilDay>::value, "");
359 static_assert(!HasDiff<absl::CivilHour, absl::CivilMonth>::value, "");
360 static_assert(!HasDiff<absl::CivilHour, absl::CivilYear>::value, "");
361
362 static_assert(!HasDiff<absl::CivilDay, absl::CivilMonth>::value, "");
363 static_assert(!HasDiff<absl::CivilDay, absl::CivilYear>::value, "");
364
365 static_assert(!HasDiff<absl::CivilMonth, absl::CivilYear>::value, "");
366 }
367
TEST(CivilTime,ValueSemantics)368 TEST(CivilTime, ValueSemantics) {
369 const absl::CivilHour a(2015, 1, 2, 3);
370 const absl::CivilHour b = a;
371 const absl::CivilHour c(b);
372 absl::CivilHour d;
373 d = c;
374 EXPECT_EQ("2015-01-02T03", absl::FormatCivilTime(d));
375 }
376
TEST(CivilTime,Relational)377 TEST(CivilTime, Relational) {
378 // Tests that the alignment unit is ignored in comparison.
379 const absl::CivilYear year(2014);
380 const absl::CivilMonth month(year);
381 EXPECT_EQ(year, month);
382
383 #define TEST_RELATIONAL(OLDER, YOUNGER) \
384 do { \
385 EXPECT_FALSE(OLDER < OLDER); \
386 EXPECT_FALSE(OLDER > OLDER); \
387 EXPECT_TRUE(OLDER >= OLDER); \
388 EXPECT_TRUE(OLDER <= OLDER); \
389 EXPECT_FALSE(YOUNGER < YOUNGER); \
390 EXPECT_FALSE(YOUNGER > YOUNGER); \
391 EXPECT_TRUE(YOUNGER >= YOUNGER); \
392 EXPECT_TRUE(YOUNGER <= YOUNGER); \
393 EXPECT_EQ(OLDER, OLDER); \
394 EXPECT_NE(OLDER, YOUNGER); \
395 EXPECT_LT(OLDER, YOUNGER); \
396 EXPECT_LE(OLDER, YOUNGER); \
397 EXPECT_GT(YOUNGER, OLDER); \
398 EXPECT_GE(YOUNGER, OLDER); \
399 } while (0)
400
401 // Alignment is ignored in comparison (verified above), so CivilSecond is
402 // used to test comparison in all field positions.
403 TEST_RELATIONAL(absl::CivilSecond(2014, 1, 1, 0, 0, 0),
404 absl::CivilSecond(2015, 1, 1, 0, 0, 0));
405 TEST_RELATIONAL(absl::CivilSecond(2014, 1, 1, 0, 0, 0),
406 absl::CivilSecond(2014, 2, 1, 0, 0, 0));
407 TEST_RELATIONAL(absl::CivilSecond(2014, 1, 1, 0, 0, 0),
408 absl::CivilSecond(2014, 1, 2, 0, 0, 0));
409 TEST_RELATIONAL(absl::CivilSecond(2014, 1, 1, 0, 0, 0),
410 absl::CivilSecond(2014, 1, 1, 1, 0, 0));
411 TEST_RELATIONAL(absl::CivilSecond(2014, 1, 1, 1, 0, 0),
412 absl::CivilSecond(2014, 1, 1, 1, 1, 0));
413 TEST_RELATIONAL(absl::CivilSecond(2014, 1, 1, 1, 1, 0),
414 absl::CivilSecond(2014, 1, 1, 1, 1, 1));
415
416 // Tests the relational operators of two different civil-time types.
417 TEST_RELATIONAL(absl::CivilDay(2014, 1, 1),
418 absl::CivilMinute(2014, 1, 1, 1, 1));
419 TEST_RELATIONAL(absl::CivilDay(2014, 1, 1),
420 absl::CivilMonth(2014, 2));
421
422 #undef TEST_RELATIONAL
423 }
424
TEST(CivilTime,Arithmetic)425 TEST(CivilTime, Arithmetic) {
426 absl::CivilSecond second(2015, 1, 2, 3, 4, 5);
427 EXPECT_EQ("2015-01-02T03:04:06", absl::FormatCivilTime(second += 1));
428 EXPECT_EQ("2015-01-02T03:04:07", absl::FormatCivilTime(second + 1));
429 EXPECT_EQ("2015-01-02T03:04:08", absl::FormatCivilTime(2 + second));
430 EXPECT_EQ("2015-01-02T03:04:05", absl::FormatCivilTime(second - 1));
431 EXPECT_EQ("2015-01-02T03:04:05", absl::FormatCivilTime(second -= 1));
432 EXPECT_EQ("2015-01-02T03:04:05", absl::FormatCivilTime(second++));
433 EXPECT_EQ("2015-01-02T03:04:07", absl::FormatCivilTime(++second));
434 EXPECT_EQ("2015-01-02T03:04:07", absl::FormatCivilTime(second--));
435 EXPECT_EQ("2015-01-02T03:04:05", absl::FormatCivilTime(--second));
436
437 absl::CivilMinute minute(2015, 1, 2, 3, 4);
438 EXPECT_EQ("2015-01-02T03:05", absl::FormatCivilTime(minute += 1));
439 EXPECT_EQ("2015-01-02T03:06", absl::FormatCivilTime(minute + 1));
440 EXPECT_EQ("2015-01-02T03:07", absl::FormatCivilTime(2 + minute));
441 EXPECT_EQ("2015-01-02T03:04", absl::FormatCivilTime(minute - 1));
442 EXPECT_EQ("2015-01-02T03:04", absl::FormatCivilTime(minute -= 1));
443 EXPECT_EQ("2015-01-02T03:04", absl::FormatCivilTime(minute++));
444 EXPECT_EQ("2015-01-02T03:06", absl::FormatCivilTime(++minute));
445 EXPECT_EQ("2015-01-02T03:06", absl::FormatCivilTime(minute--));
446 EXPECT_EQ("2015-01-02T03:04", absl::FormatCivilTime(--minute));
447
448 absl::CivilHour hour(2015, 1, 2, 3);
449 EXPECT_EQ("2015-01-02T04", absl::FormatCivilTime(hour += 1));
450 EXPECT_EQ("2015-01-02T05", absl::FormatCivilTime(hour + 1));
451 EXPECT_EQ("2015-01-02T06", absl::FormatCivilTime(2 + hour));
452 EXPECT_EQ("2015-01-02T03", absl::FormatCivilTime(hour - 1));
453 EXPECT_EQ("2015-01-02T03", absl::FormatCivilTime(hour -= 1));
454 EXPECT_EQ("2015-01-02T03", absl::FormatCivilTime(hour++));
455 EXPECT_EQ("2015-01-02T05", absl::FormatCivilTime(++hour));
456 EXPECT_EQ("2015-01-02T05", absl::FormatCivilTime(hour--));
457 EXPECT_EQ("2015-01-02T03", absl::FormatCivilTime(--hour));
458
459 absl::CivilDay day(2015, 1, 2);
460 EXPECT_EQ("2015-01-03", absl::FormatCivilTime(day += 1));
461 EXPECT_EQ("2015-01-04", absl::FormatCivilTime(day + 1));
462 EXPECT_EQ("2015-01-05", absl::FormatCivilTime(2 + day));
463 EXPECT_EQ("2015-01-02", absl::FormatCivilTime(day - 1));
464 EXPECT_EQ("2015-01-02", absl::FormatCivilTime(day -= 1));
465 EXPECT_EQ("2015-01-02", absl::FormatCivilTime(day++));
466 EXPECT_EQ("2015-01-04", absl::FormatCivilTime(++day));
467 EXPECT_EQ("2015-01-04", absl::FormatCivilTime(day--));
468 EXPECT_EQ("2015-01-02", absl::FormatCivilTime(--day));
469
470 absl::CivilMonth month(2015, 1);
471 EXPECT_EQ("2015-02", absl::FormatCivilTime(month += 1));
472 EXPECT_EQ("2015-03", absl::FormatCivilTime(month + 1));
473 EXPECT_EQ("2015-04", absl::FormatCivilTime(2 + month));
474 EXPECT_EQ("2015-01", absl::FormatCivilTime(month - 1));
475 EXPECT_EQ("2015-01", absl::FormatCivilTime(month -= 1));
476 EXPECT_EQ("2015-01", absl::FormatCivilTime(month++));
477 EXPECT_EQ("2015-03", absl::FormatCivilTime(++month));
478 EXPECT_EQ("2015-03", absl::FormatCivilTime(month--));
479 EXPECT_EQ("2015-01", absl::FormatCivilTime(--month));
480
481 absl::CivilYear year(2015);
482 EXPECT_EQ("2016", absl::FormatCivilTime(year += 1));
483 EXPECT_EQ("2017", absl::FormatCivilTime(year + 1));
484 EXPECT_EQ("2018", absl::FormatCivilTime(2 + year));
485 EXPECT_EQ("2015", absl::FormatCivilTime(year - 1));
486 EXPECT_EQ("2015", absl::FormatCivilTime(year -= 1));
487 EXPECT_EQ("2015", absl::FormatCivilTime(year++));
488 EXPECT_EQ("2017", absl::FormatCivilTime(++year));
489 EXPECT_EQ("2017", absl::FormatCivilTime(year--));
490 EXPECT_EQ("2015", absl::FormatCivilTime(--year));
491 }
492
TEST(CivilTime,ArithmeticLimits)493 TEST(CivilTime, ArithmeticLimits) {
494 const int kIntMax = std::numeric_limits<int>::max();
495 const int kIntMin = std::numeric_limits<int>::min();
496
497 absl::CivilSecond second(1970, 1, 1, 0, 0, 0);
498 second += kIntMax;
499 EXPECT_EQ("2038-01-19T03:14:07", absl::FormatCivilTime(second));
500 second -= kIntMax;
501 EXPECT_EQ("1970-01-01T00:00:00", absl::FormatCivilTime(second));
502 second += kIntMin;
503 EXPECT_EQ("1901-12-13T20:45:52", absl::FormatCivilTime(second));
504 second -= kIntMin;
505 EXPECT_EQ("1970-01-01T00:00:00", absl::FormatCivilTime(second));
506
507 absl::CivilMinute minute(1970, 1, 1, 0, 0);
508 minute += kIntMax;
509 EXPECT_EQ("6053-01-23T02:07", absl::FormatCivilTime(minute));
510 minute -= kIntMax;
511 EXPECT_EQ("1970-01-01T00:00", absl::FormatCivilTime(minute));
512 minute += kIntMin;
513 EXPECT_EQ("-2114-12-08T21:52", absl::FormatCivilTime(minute));
514 minute -= kIntMin;
515 EXPECT_EQ("1970-01-01T00:00", absl::FormatCivilTime(minute));
516
517 absl::CivilHour hour(1970, 1, 1, 0);
518 hour += kIntMax;
519 EXPECT_EQ("246953-10-09T07", absl::FormatCivilTime(hour));
520 hour -= kIntMax;
521 EXPECT_EQ("1970-01-01T00", absl::FormatCivilTime(hour));
522 hour += kIntMin;
523 EXPECT_EQ("-243014-03-24T16", absl::FormatCivilTime(hour));
524 hour -= kIntMin;
525 EXPECT_EQ("1970-01-01T00", absl::FormatCivilTime(hour));
526
527 absl::CivilDay day(1970, 1, 1);
528 day += kIntMax;
529 EXPECT_EQ("5881580-07-11", absl::FormatCivilTime(day));
530 day -= kIntMax;
531 EXPECT_EQ("1970-01-01", absl::FormatCivilTime(day));
532 day += kIntMin;
533 EXPECT_EQ("-5877641-06-23", absl::FormatCivilTime(day));
534 day -= kIntMin;
535 EXPECT_EQ("1970-01-01", absl::FormatCivilTime(day));
536
537 absl::CivilMonth month(1970, 1);
538 month += kIntMax;
539 EXPECT_EQ("178958940-08", absl::FormatCivilTime(month));
540 month -= kIntMax;
541 EXPECT_EQ("1970-01", absl::FormatCivilTime(month));
542 month += kIntMin;
543 EXPECT_EQ("-178955001-05", absl::FormatCivilTime(month));
544 month -= kIntMin;
545 EXPECT_EQ("1970-01", absl::FormatCivilTime(month));
546
547 absl::CivilYear year(0);
548 year += kIntMax;
549 EXPECT_EQ("2147483647", absl::FormatCivilTime(year));
550 year -= kIntMax;
551 EXPECT_EQ("0", absl::FormatCivilTime(year));
552 year += kIntMin;
553 EXPECT_EQ("-2147483648", absl::FormatCivilTime(year));
554 year -= kIntMin;
555 EXPECT_EQ("0", absl::FormatCivilTime(year));
556 }
557
TEST(CivilTime,Difference)558 TEST(CivilTime, Difference) {
559 absl::CivilSecond second(2015, 1, 2, 3, 4, 5);
560 EXPECT_EQ(0, second - second);
561 EXPECT_EQ(10, (second + 10) - second);
562 EXPECT_EQ(-10, (second - 10) - second);
563
564 absl::CivilMinute minute(2015, 1, 2, 3, 4);
565 EXPECT_EQ(0, minute - minute);
566 EXPECT_EQ(10, (minute + 10) - minute);
567 EXPECT_EQ(-10, (minute - 10) - minute);
568
569 absl::CivilHour hour(2015, 1, 2, 3);
570 EXPECT_EQ(0, hour - hour);
571 EXPECT_EQ(10, (hour + 10) - hour);
572 EXPECT_EQ(-10, (hour - 10) - hour);
573
574 absl::CivilDay day(2015, 1, 2);
575 EXPECT_EQ(0, day - day);
576 EXPECT_EQ(10, (day + 10) - day);
577 EXPECT_EQ(-10, (day - 10) - day);
578
579 absl::CivilMonth month(2015, 1);
580 EXPECT_EQ(0, month - month);
581 EXPECT_EQ(10, (month + 10) - month);
582 EXPECT_EQ(-10, (month - 10) - month);
583
584 absl::CivilYear year(2015);
585 EXPECT_EQ(0, year - year);
586 EXPECT_EQ(10, (year + 10) - year);
587 EXPECT_EQ(-10, (year - 10) - year);
588 }
589
TEST(CivilTime,DifferenceLimits)590 TEST(CivilTime, DifferenceLimits) {
591 const absl::civil_diff_t kDiffMax =
592 std::numeric_limits<absl::civil_diff_t>::max();
593 const absl::civil_diff_t kDiffMin =
594 std::numeric_limits<absl::civil_diff_t>::min();
595
596 // Check day arithmetic at the end of the year range.
597 const absl::CivilDay max_day(kDiffMax, 12, 31);
598 EXPECT_EQ(1, max_day - (max_day - 1));
599 EXPECT_EQ(-1, (max_day - 1) - max_day);
600
601 // Check day arithmetic at the start of the year range.
602 const absl::CivilDay min_day(kDiffMin, 1, 1);
603 EXPECT_EQ(1, (min_day + 1) - min_day);
604 EXPECT_EQ(-1, min_day - (min_day + 1));
605
606 // Check the limits of the return value.
607 const absl::CivilDay d1(1970, 1, 1);
608 const absl::CivilDay d2(25252734927768524, 7, 27);
609 EXPECT_EQ(kDiffMax, d2 - d1);
610 EXPECT_EQ(kDiffMin, d1 - (d2 + 1));
611 }
612
TEST(CivilTime,Properties)613 TEST(CivilTime, Properties) {
614 absl::CivilSecond ss(2015, 2, 3, 4, 5, 6);
615 EXPECT_EQ(2015, ss.year());
616 EXPECT_EQ(2, ss.month());
617 EXPECT_EQ(3, ss.day());
618 EXPECT_EQ(4, ss.hour());
619 EXPECT_EQ(5, ss.minute());
620 EXPECT_EQ(6, ss.second());
621 EXPECT_EQ(absl::Weekday::tuesday, absl::GetWeekday(ss));
622 EXPECT_EQ(34, absl::GetYearDay(ss));
623
624 absl::CivilMinute mm(2015, 2, 3, 4, 5, 6);
625 EXPECT_EQ(2015, mm.year());
626 EXPECT_EQ(2, mm.month());
627 EXPECT_EQ(3, mm.day());
628 EXPECT_EQ(4, mm.hour());
629 EXPECT_EQ(5, mm.minute());
630 EXPECT_EQ(0, mm.second());
631 EXPECT_EQ(absl::Weekday::tuesday, absl::GetWeekday(mm));
632 EXPECT_EQ(34, absl::GetYearDay(mm));
633
634 absl::CivilHour hh(2015, 2, 3, 4, 5, 6);
635 EXPECT_EQ(2015, hh.year());
636 EXPECT_EQ(2, hh.month());
637 EXPECT_EQ(3, hh.day());
638 EXPECT_EQ(4, hh.hour());
639 EXPECT_EQ(0, hh.minute());
640 EXPECT_EQ(0, hh.second());
641 EXPECT_EQ(absl::Weekday::tuesday, absl::GetWeekday(hh));
642 EXPECT_EQ(34, absl::GetYearDay(hh));
643
644 absl::CivilDay d(2015, 2, 3, 4, 5, 6);
645 EXPECT_EQ(2015, d.year());
646 EXPECT_EQ(2, d.month());
647 EXPECT_EQ(3, d.day());
648 EXPECT_EQ(0, d.hour());
649 EXPECT_EQ(0, d.minute());
650 EXPECT_EQ(0, d.second());
651 EXPECT_EQ(absl::Weekday::tuesday, absl::GetWeekday(d));
652 EXPECT_EQ(34, absl::GetYearDay(d));
653
654 absl::CivilMonth m(2015, 2, 3, 4, 5, 6);
655 EXPECT_EQ(2015, m.year());
656 EXPECT_EQ(2, m.month());
657 EXPECT_EQ(1, m.day());
658 EXPECT_EQ(0, m.hour());
659 EXPECT_EQ(0, m.minute());
660 EXPECT_EQ(0, m.second());
661 EXPECT_EQ(absl::Weekday::sunday, absl::GetWeekday(m));
662 EXPECT_EQ(32, absl::GetYearDay(m));
663
664 absl::CivilYear y(2015, 2, 3, 4, 5, 6);
665 EXPECT_EQ(2015, y.year());
666 EXPECT_EQ(1, y.month());
667 EXPECT_EQ(1, y.day());
668 EXPECT_EQ(0, y.hour());
669 EXPECT_EQ(0, y.minute());
670 EXPECT_EQ(0, y.second());
671 EXPECT_EQ(absl::Weekday::thursday, absl::GetWeekday(y));
672 EXPECT_EQ(1, absl::GetYearDay(y));
673 }
674
TEST(CivilTime,Format)675 TEST(CivilTime, Format) {
676 absl::CivilSecond ss;
677 EXPECT_EQ("1970-01-01T00:00:00", absl::FormatCivilTime(ss));
678
679 absl::CivilMinute mm;
680 EXPECT_EQ("1970-01-01T00:00", absl::FormatCivilTime(mm));
681
682 absl::CivilHour hh;
683 EXPECT_EQ("1970-01-01T00", absl::FormatCivilTime(hh));
684
685 absl::CivilDay d;
686 EXPECT_EQ("1970-01-01", absl::FormatCivilTime(d));
687
688 absl::CivilMonth m;
689 EXPECT_EQ("1970-01", absl::FormatCivilTime(m));
690
691 absl::CivilYear y;
692 EXPECT_EQ("1970", absl::FormatCivilTime(y));
693 }
694
TEST(CivilTime,Parse)695 TEST(CivilTime, Parse) {
696 absl::CivilSecond ss;
697 absl::CivilMinute mm;
698 absl::CivilHour hh;
699 absl::CivilDay d;
700 absl::CivilMonth m;
701 absl::CivilYear y;
702
703 // CivilSecond OK; others fail
704 EXPECT_TRUE(absl::ParseCivilTime("2015-01-02T03:04:05", &ss));
705 EXPECT_EQ("2015-01-02T03:04:05", absl::FormatCivilTime(ss));
706 EXPECT_FALSE(absl::ParseCivilTime("2015-01-02T03:04:05", &mm));
707 EXPECT_FALSE(absl::ParseCivilTime("2015-01-02T03:04:05", &hh));
708 EXPECT_FALSE(absl::ParseCivilTime("2015-01-02T03:04:05", &d));
709 EXPECT_FALSE(absl::ParseCivilTime("2015-01-02T03:04:05", &m));
710 EXPECT_FALSE(absl::ParseCivilTime("2015-01-02T03:04:05", &y));
711
712 // CivilMinute OK; others fail
713 EXPECT_FALSE(absl::ParseCivilTime("2015-01-02T03:04", &ss));
714 EXPECT_TRUE(absl::ParseCivilTime("2015-01-02T03:04", &mm));
715 EXPECT_EQ("2015-01-02T03:04", absl::FormatCivilTime(mm));
716 EXPECT_FALSE(absl::ParseCivilTime("2015-01-02T03:04", &hh));
717 EXPECT_FALSE(absl::ParseCivilTime("2015-01-02T03:04", &d));
718 EXPECT_FALSE(absl::ParseCivilTime("2015-01-02T03:04", &m));
719 EXPECT_FALSE(absl::ParseCivilTime("2015-01-02T03:04", &y));
720
721 // CivilHour OK; others fail
722 EXPECT_FALSE(absl::ParseCivilTime("2015-01-02T03", &ss));
723 EXPECT_FALSE(absl::ParseCivilTime("2015-01-02T03", &mm));
724 EXPECT_TRUE(absl::ParseCivilTime("2015-01-02T03", &hh));
725 EXPECT_EQ("2015-01-02T03", absl::FormatCivilTime(hh));
726 EXPECT_FALSE(absl::ParseCivilTime("2015-01-02T03", &d));
727 EXPECT_FALSE(absl::ParseCivilTime("2015-01-02T03", &m));
728 EXPECT_FALSE(absl::ParseCivilTime("2015-01-02T03", &y));
729
730 // CivilDay OK; others fail
731 EXPECT_FALSE(absl::ParseCivilTime("2015-01-02", &ss));
732 EXPECT_FALSE(absl::ParseCivilTime("2015-01-02", &mm));
733 EXPECT_FALSE(absl::ParseCivilTime("2015-01-02", &hh));
734 EXPECT_TRUE(absl::ParseCivilTime("2015-01-02", &d));
735 EXPECT_EQ("2015-01-02", absl::FormatCivilTime(d));
736 EXPECT_FALSE(absl::ParseCivilTime("2015-01-02", &m));
737 EXPECT_FALSE(absl::ParseCivilTime("2015-01-02", &y));
738
739 // CivilMonth OK; others fail
740 EXPECT_FALSE(absl::ParseCivilTime("2015-01", &ss));
741 EXPECT_FALSE(absl::ParseCivilTime("2015-01", &mm));
742 EXPECT_FALSE(absl::ParseCivilTime("2015-01", &hh));
743 EXPECT_FALSE(absl::ParseCivilTime("2015-01", &d));
744 EXPECT_TRUE(absl::ParseCivilTime("2015-01", &m));
745 EXPECT_EQ("2015-01", absl::FormatCivilTime(m));
746 EXPECT_FALSE(absl::ParseCivilTime("2015-01", &y));
747
748 // CivilYear OK; others fail
749 EXPECT_FALSE(absl::ParseCivilTime("2015", &ss));
750 EXPECT_FALSE(absl::ParseCivilTime("2015", &mm));
751 EXPECT_FALSE(absl::ParseCivilTime("2015", &hh));
752 EXPECT_FALSE(absl::ParseCivilTime("2015", &d));
753 EXPECT_FALSE(absl::ParseCivilTime("2015", &m));
754 EXPECT_TRUE(absl::ParseCivilTime("2015", &y));
755 EXPECT_EQ("2015", absl::FormatCivilTime(y));
756 }
757
TEST(CivilTime,FormatAndParseLenient)758 TEST(CivilTime, FormatAndParseLenient) {
759 absl::CivilSecond ss;
760 EXPECT_EQ("1970-01-01T00:00:00", absl::FormatCivilTime(ss));
761
762 absl::CivilMinute mm;
763 EXPECT_EQ("1970-01-01T00:00", absl::FormatCivilTime(mm));
764
765 absl::CivilHour hh;
766 EXPECT_EQ("1970-01-01T00", absl::FormatCivilTime(hh));
767
768 absl::CivilDay d;
769 EXPECT_EQ("1970-01-01", absl::FormatCivilTime(d));
770
771 absl::CivilMonth m;
772 EXPECT_EQ("1970-01", absl::FormatCivilTime(m));
773
774 absl::CivilYear y;
775 EXPECT_EQ("1970", absl::FormatCivilTime(y));
776
777 EXPECT_TRUE(absl::ParseLenientCivilTime("2015-01-02T03:04:05", &ss));
778 EXPECT_EQ("2015-01-02T03:04:05", absl::FormatCivilTime(ss));
779
780 EXPECT_TRUE(absl::ParseLenientCivilTime("2015-01-02T03:04:05", &mm));
781 EXPECT_EQ("2015-01-02T03:04", absl::FormatCivilTime(mm));
782
783 EXPECT_TRUE(absl::ParseLenientCivilTime("2015-01-02T03:04:05", &hh));
784 EXPECT_EQ("2015-01-02T03", absl::FormatCivilTime(hh));
785
786 EXPECT_TRUE(absl::ParseLenientCivilTime("2015-01-02T03:04:05", &d));
787 EXPECT_EQ("2015-01-02", absl::FormatCivilTime(d));
788
789 EXPECT_TRUE(absl::ParseLenientCivilTime("2015-01-02T03:04:05", &m));
790 EXPECT_EQ("2015-01", absl::FormatCivilTime(m));
791
792 EXPECT_TRUE(absl::ParseLenientCivilTime("2015-01-02T03:04:05", &y));
793 EXPECT_EQ("2015", absl::FormatCivilTime(y));
794 }
795
TEST(CivilTime,ParseEdgeCases)796 TEST(CivilTime, ParseEdgeCases) {
797 absl::CivilSecond ss;
798 EXPECT_TRUE(
799 absl::ParseLenientCivilTime("9223372036854775807-12-31T23:59:59", &ss));
800 EXPECT_EQ("9223372036854775807-12-31T23:59:59", absl::FormatCivilTime(ss));
801 EXPECT_TRUE(
802 absl::ParseLenientCivilTime("-9223372036854775808-01-01T00:00:00", &ss));
803 EXPECT_EQ("-9223372036854775808-01-01T00:00:00", absl::FormatCivilTime(ss));
804
805 absl::CivilMinute mm;
806 EXPECT_TRUE(
807 absl::ParseLenientCivilTime("9223372036854775807-12-31T23:59", &mm));
808 EXPECT_EQ("9223372036854775807-12-31T23:59", absl::FormatCivilTime(mm));
809 EXPECT_TRUE(
810 absl::ParseLenientCivilTime("-9223372036854775808-01-01T00:00", &mm));
811 EXPECT_EQ("-9223372036854775808-01-01T00:00", absl::FormatCivilTime(mm));
812
813 absl::CivilHour hh;
814 EXPECT_TRUE(
815 absl::ParseLenientCivilTime("9223372036854775807-12-31T23", &hh));
816 EXPECT_EQ("9223372036854775807-12-31T23", absl::FormatCivilTime(hh));
817 EXPECT_TRUE(
818 absl::ParseLenientCivilTime("-9223372036854775808-01-01T00", &hh));
819 EXPECT_EQ("-9223372036854775808-01-01T00", absl::FormatCivilTime(hh));
820
821 absl::CivilDay d;
822 EXPECT_TRUE(absl::ParseLenientCivilTime("9223372036854775807-12-31", &d));
823 EXPECT_EQ("9223372036854775807-12-31", absl::FormatCivilTime(d));
824 EXPECT_TRUE(absl::ParseLenientCivilTime("-9223372036854775808-01-01", &d));
825 EXPECT_EQ("-9223372036854775808-01-01", absl::FormatCivilTime(d));
826
827 absl::CivilMonth m;
828 EXPECT_TRUE(absl::ParseLenientCivilTime("9223372036854775807-12", &m));
829 EXPECT_EQ("9223372036854775807-12", absl::FormatCivilTime(m));
830 EXPECT_TRUE(absl::ParseLenientCivilTime("-9223372036854775808-01", &m));
831 EXPECT_EQ("-9223372036854775808-01", absl::FormatCivilTime(m));
832
833 absl::CivilYear y;
834 EXPECT_TRUE(absl::ParseLenientCivilTime("9223372036854775807", &y));
835 EXPECT_EQ("9223372036854775807", absl::FormatCivilTime(y));
836 EXPECT_TRUE(absl::ParseLenientCivilTime("-9223372036854775808", &y));
837 EXPECT_EQ("-9223372036854775808", absl::FormatCivilTime(y));
838
839 // Tests some valid, but interesting, cases
840 EXPECT_TRUE(absl::ParseLenientCivilTime("0", &ss)) << ss;
841 EXPECT_EQ(absl::CivilYear(0), ss);
842 EXPECT_TRUE(absl::ParseLenientCivilTime("0-1", &ss)) << ss;
843 EXPECT_EQ(absl::CivilMonth(0, 1), ss);
844 EXPECT_TRUE(absl::ParseLenientCivilTime(" 2015 ", &ss)) << ss;
845 EXPECT_EQ(absl::CivilYear(2015), ss);
846 EXPECT_TRUE(absl::ParseLenientCivilTime(" 2015-6 ", &ss)) << ss;
847 EXPECT_EQ(absl::CivilMonth(2015, 6), ss);
848 EXPECT_TRUE(absl::ParseLenientCivilTime("2015-6-7", &ss)) << ss;
849 EXPECT_EQ(absl::CivilDay(2015, 6, 7), ss);
850 EXPECT_TRUE(absl::ParseLenientCivilTime(" 2015-6-7 ", &ss)) << ss;
851 EXPECT_EQ(absl::CivilDay(2015, 6, 7), ss);
852 EXPECT_TRUE(absl::ParseLenientCivilTime("2015-06-07T10:11:12 ", &ss)) << ss;
853 EXPECT_EQ(absl::CivilSecond(2015, 6, 7, 10, 11, 12), ss);
854 EXPECT_TRUE(absl::ParseLenientCivilTime(" 2015-06-07T10:11:12 ", &ss)) << ss;
855 EXPECT_EQ(absl::CivilSecond(2015, 6, 7, 10, 11, 12), ss);
856 EXPECT_TRUE(absl::ParseLenientCivilTime("-01-01", &ss)) << ss;
857 EXPECT_EQ(absl::CivilMonth(-1, 1), ss);
858
859 // Tests some invalid cases
860 EXPECT_FALSE(absl::ParseLenientCivilTime("01-01-2015", &ss)) << ss;
861 EXPECT_FALSE(absl::ParseLenientCivilTime("2015-", &ss)) << ss;
862 EXPECT_FALSE(absl::ParseLenientCivilTime("0xff-01", &ss)) << ss;
863 EXPECT_FALSE(absl::ParseLenientCivilTime("2015-02-30T04:05:06", &ss)) << ss;
864 EXPECT_FALSE(absl::ParseLenientCivilTime("2015-02-03T04:05:96", &ss)) << ss;
865 EXPECT_FALSE(absl::ParseLenientCivilTime("X2015-02-03T04:05:06", &ss)) << ss;
866 EXPECT_FALSE(absl::ParseLenientCivilTime("2015-02-03T04:05:003", &ss)) << ss;
867 EXPECT_FALSE(absl::ParseLenientCivilTime("2015 -02-03T04:05:06", &ss)) << ss;
868 EXPECT_FALSE(absl::ParseLenientCivilTime("2015-02-03-04:05:06", &ss)) << ss;
869 EXPECT_FALSE(absl::ParseLenientCivilTime("2015:02:03T04-05-06", &ss)) << ss;
870 EXPECT_FALSE(absl::ParseLenientCivilTime("9223372036854775808", &y)) << y;
871 }
872
TEST(CivilTime,AbslStringify)873 TEST(CivilTime, AbslStringify) {
874 EXPECT_EQ("2015-01-02T03:04:05",
875 absl::StrFormat("%v", absl::CivilSecond(2015, 1, 2, 3, 4, 5)));
876
877 EXPECT_EQ("2015-01-02T03:04",
878 absl::StrFormat("%v", absl::CivilMinute(2015, 1, 2, 3, 4)));
879
880 EXPECT_EQ("2015-01-02T03",
881 absl::StrFormat("%v", absl::CivilHour(2015, 1, 2, 3)));
882
883 EXPECT_EQ("2015-01-02", absl::StrFormat("%v", absl::CivilDay(2015, 1, 2)));
884
885 EXPECT_EQ("2015-01", absl::StrFormat("%v", absl::CivilMonth(2015, 1)));
886
887 EXPECT_EQ("2015", absl::StrFormat("%v", absl::CivilYear(2015)));
888 }
889
TEST(CivilTime,OutputStream)890 TEST(CivilTime, OutputStream) {
891 absl::CivilSecond cs(2016, 2, 3, 4, 5, 6);
892 {
893 std::stringstream ss;
894 ss << std::left << std::setfill('.');
895 ss << std::setw(3) << 'X';
896 ss << std::setw(21) << absl::CivilYear(cs);
897 ss << std::setw(3) << 'X';
898 EXPECT_EQ("X..2016.................X..", ss.str());
899 }
900 {
901 std::stringstream ss;
902 ss << std::left << std::setfill('.');
903 ss << std::setw(3) << 'X';
904 ss << std::setw(21) << absl::CivilMonth(cs);
905 ss << std::setw(3) << 'X';
906 EXPECT_EQ("X..2016-02..............X..", ss.str());
907 }
908 {
909 std::stringstream ss;
910 ss << std::left << std::setfill('.');
911 ss << std::setw(3) << 'X';
912 ss << std::setw(21) << absl::CivilDay(cs);
913 ss << std::setw(3) << 'X';
914 EXPECT_EQ("X..2016-02-03...........X..", ss.str());
915 }
916 {
917 std::stringstream ss;
918 ss << std::left << std::setfill('.');
919 ss << std::setw(3) << 'X';
920 ss << std::setw(21) << absl::CivilHour(cs);
921 ss << std::setw(3) << 'X';
922 EXPECT_EQ("X..2016-02-03T04........X..", ss.str());
923 }
924 {
925 std::stringstream ss;
926 ss << std::left << std::setfill('.');
927 ss << std::setw(3) << 'X';
928 ss << std::setw(21) << absl::CivilMinute(cs);
929 ss << std::setw(3) << 'X';
930 EXPECT_EQ("X..2016-02-03T04:05.....X..", ss.str());
931 }
932 {
933 std::stringstream ss;
934 ss << std::left << std::setfill('.');
935 ss << std::setw(3) << 'X';
936 ss << std::setw(21) << absl::CivilSecond(cs);
937 ss << std::setw(3) << 'X';
938 EXPECT_EQ("X..2016-02-03T04:05:06..X..", ss.str());
939 }
940 {
941 std::stringstream ss;
942 ss << std::left << std::setfill('.');
943 ss << std::setw(3) << 'X';
944 ss << std::setw(21) << absl::Weekday::wednesday;
945 ss << std::setw(3) << 'X';
946 EXPECT_EQ("X..Wednesday............X..", ss.str());
947 }
948 }
949
TEST(CivilTime,Weekday)950 TEST(CivilTime, Weekday) {
951 absl::CivilDay d(1970, 1, 1);
952 EXPECT_EQ(absl::Weekday::thursday, absl::GetWeekday(d)) << d;
953
954 // We used to get this wrong for years < -30.
955 d = absl::CivilDay(-31, 12, 24);
956 EXPECT_EQ(absl::Weekday::wednesday, absl::GetWeekday(d)) << d;
957 }
958
TEST(CivilTime,NextPrevWeekday)959 TEST(CivilTime, NextPrevWeekday) {
960 // Jan 1, 1970 was a Thursday.
961 const absl::CivilDay thursday(1970, 1, 1);
962
963 // Thursday -> Thursday
964 absl::CivilDay d = absl::NextWeekday(thursday, absl::Weekday::thursday);
965 EXPECT_EQ(7, d - thursday) << d;
966 EXPECT_EQ(d - 14, absl::PrevWeekday(thursday, absl::Weekday::thursday));
967
968 // Thursday -> Friday
969 d = absl::NextWeekday(thursday, absl::Weekday::friday);
970 EXPECT_EQ(1, d - thursday) << d;
971 EXPECT_EQ(d - 7, absl::PrevWeekday(thursday, absl::Weekday::friday));
972
973 // Thursday -> Saturday
974 d = absl::NextWeekday(thursday, absl::Weekday::saturday);
975 EXPECT_EQ(2, d - thursday) << d;
976 EXPECT_EQ(d - 7, absl::PrevWeekday(thursday, absl::Weekday::saturday));
977
978 // Thursday -> Sunday
979 d = absl::NextWeekday(thursday, absl::Weekday::sunday);
980 EXPECT_EQ(3, d - thursday) << d;
981 EXPECT_EQ(d - 7, absl::PrevWeekday(thursday, absl::Weekday::sunday));
982
983 // Thursday -> Monday
984 d = absl::NextWeekday(thursday, absl::Weekday::monday);
985 EXPECT_EQ(4, d - thursday) << d;
986 EXPECT_EQ(d - 7, absl::PrevWeekday(thursday, absl::Weekday::monday));
987
988 // Thursday -> Tuesday
989 d = absl::NextWeekday(thursday, absl::Weekday::tuesday);
990 EXPECT_EQ(5, d - thursday) << d;
991 EXPECT_EQ(d - 7, absl::PrevWeekday(thursday, absl::Weekday::tuesday));
992
993 // Thursday -> Wednesday
994 d = absl::NextWeekday(thursday, absl::Weekday::wednesday);
995 EXPECT_EQ(6, d - thursday) << d;
996 EXPECT_EQ(d - 7, absl::PrevWeekday(thursday, absl::Weekday::wednesday));
997 }
998
999 // NOTE: Run this with --copt=-ftrapv to detect overflow problems.
TEST(CivilTime,DifferenceWithHugeYear)1000 TEST(CivilTime, DifferenceWithHugeYear) {
1001 absl::CivilDay d1(9223372036854775807, 1, 1);
1002 absl::CivilDay d2(9223372036854775807, 12, 31);
1003 EXPECT_EQ(364, d2 - d1);
1004
1005 d1 = absl::CivilDay(-9223372036854775807 - 1, 1, 1);
1006 d2 = absl::CivilDay(-9223372036854775807 - 1, 12, 31);
1007 EXPECT_EQ(365, d2 - d1);
1008
1009 // Check the limits of the return value at the end of the year range.
1010 d1 = absl::CivilDay(9223372036854775807, 1, 1);
1011 d2 = absl::CivilDay(9198119301927009252, 6, 6);
1012 EXPECT_EQ(9223372036854775807, d1 - d2);
1013 d2 = d2 - 1;
1014 EXPECT_EQ(-9223372036854775807 - 1, d2 - d1);
1015
1016 // Check the limits of the return value at the start of the year range.
1017 d1 = absl::CivilDay(-9223372036854775807 - 1, 1, 1);
1018 d2 = absl::CivilDay(-9198119301927009254, 7, 28);
1019 EXPECT_EQ(9223372036854775807, d2 - d1);
1020 d2 = d2 + 1;
1021 EXPECT_EQ(-9223372036854775807 - 1, d1 - d2);
1022
1023 // Check the limits of the return value from either side of year 0.
1024 d1 = absl::CivilDay(-12626367463883278, 9, 3);
1025 d2 = absl::CivilDay(12626367463883277, 3, 28);
1026 EXPECT_EQ(9223372036854775807, d2 - d1);
1027 d2 = d2 + 1;
1028 EXPECT_EQ(-9223372036854775807 - 1, d1 - d2);
1029 }
1030
1031 // NOTE: Run this with --copt=-ftrapv to detect overflow problems.
TEST(CivilTime,DifferenceNoIntermediateOverflow)1032 TEST(CivilTime, DifferenceNoIntermediateOverflow) {
1033 // The difference up to the minute field would be below the minimum
1034 // int64_t, but the 52 extra seconds brings us back to the minimum.
1035 absl::CivilSecond s1(-292277022657, 1, 27, 8, 29 - 1, 52);
1036 absl::CivilSecond s2(1970, 1, 1, 0, 0 - 1, 0);
1037 EXPECT_EQ(-9223372036854775807 - 1, s1 - s2);
1038
1039 // The difference up to the minute field would be above the maximum
1040 // int64_t, but the -53 extra seconds brings us back to the maximum.
1041 s1 = absl::CivilSecond(292277026596, 12, 4, 15, 30, 7 - 7);
1042 s2 = absl::CivilSecond(1970, 1, 1, 0, 0, 0 - 7);
1043 EXPECT_EQ(9223372036854775807, s1 - s2);
1044 }
1045
TEST(CivilTime,NormalizeSimpleOverflow)1046 TEST(CivilTime, NormalizeSimpleOverflow) {
1047 absl::CivilSecond cs;
1048 cs = absl::CivilSecond(2013, 11, 15, 16, 32, 59 + 1);
1049 EXPECT_EQ("2013-11-15T16:33:00", absl::FormatCivilTime(cs));
1050 cs = absl::CivilSecond(2013, 11, 15, 16, 59 + 1, 14);
1051 EXPECT_EQ("2013-11-15T17:00:14", absl::FormatCivilTime(cs));
1052 cs = absl::CivilSecond(2013, 11, 15, 23 + 1, 32, 14);
1053 EXPECT_EQ("2013-11-16T00:32:14", absl::FormatCivilTime(cs));
1054 cs = absl::CivilSecond(2013, 11, 30 + 1, 16, 32, 14);
1055 EXPECT_EQ("2013-12-01T16:32:14", absl::FormatCivilTime(cs));
1056 cs = absl::CivilSecond(2013, 12 + 1, 15, 16, 32, 14);
1057 EXPECT_EQ("2014-01-15T16:32:14", absl::FormatCivilTime(cs));
1058 }
1059
TEST(CivilTime,NormalizeSimpleUnderflow)1060 TEST(CivilTime, NormalizeSimpleUnderflow) {
1061 absl::CivilSecond cs;
1062 cs = absl::CivilSecond(2013, 11, 15, 16, 32, 0 - 1);
1063 EXPECT_EQ("2013-11-15T16:31:59", absl::FormatCivilTime(cs));
1064 cs = absl::CivilSecond(2013, 11, 15, 16, 0 - 1, 14);
1065 EXPECT_EQ("2013-11-15T15:59:14", absl::FormatCivilTime(cs));
1066 cs = absl::CivilSecond(2013, 11, 15, 0 - 1, 32, 14);
1067 EXPECT_EQ("2013-11-14T23:32:14", absl::FormatCivilTime(cs));
1068 cs = absl::CivilSecond(2013, 11, 1 - 1, 16, 32, 14);
1069 EXPECT_EQ("2013-10-31T16:32:14", absl::FormatCivilTime(cs));
1070 cs = absl::CivilSecond(2013, 1 - 1, 15, 16, 32, 14);
1071 EXPECT_EQ("2012-12-15T16:32:14", absl::FormatCivilTime(cs));
1072 }
1073
TEST(CivilTime,NormalizeMultipleOverflow)1074 TEST(CivilTime, NormalizeMultipleOverflow) {
1075 absl::CivilSecond cs(2013, 12, 31, 23, 59, 59 + 1);
1076 EXPECT_EQ("2014-01-01T00:00:00", absl::FormatCivilTime(cs));
1077 }
1078
TEST(CivilTime,NormalizeMultipleUnderflow)1079 TEST(CivilTime, NormalizeMultipleUnderflow) {
1080 absl::CivilSecond cs(2014, 1, 1, 0, 0, 0 - 1);
1081 EXPECT_EQ("2013-12-31T23:59:59", absl::FormatCivilTime(cs));
1082 }
1083
TEST(CivilTime,NormalizeOverflowLimits)1084 TEST(CivilTime, NormalizeOverflowLimits) {
1085 absl::CivilSecond cs;
1086
1087 const int kintmax = std::numeric_limits<int>::max();
1088 cs = absl::CivilSecond(0, kintmax, kintmax, kintmax, kintmax, kintmax);
1089 EXPECT_EQ("185085715-11-27T12:21:07", absl::FormatCivilTime(cs));
1090
1091 const int kintmin = std::numeric_limits<int>::min();
1092 cs = absl::CivilSecond(0, kintmin, kintmin, kintmin, kintmin, kintmin);
1093 EXPECT_EQ("-185085717-10-31T10:37:52", absl::FormatCivilTime(cs));
1094 }
1095
TEST(CivilTime,NormalizeComplexOverflow)1096 TEST(CivilTime, NormalizeComplexOverflow) {
1097 absl::CivilSecond cs;
1098 cs = absl::CivilSecond(2013, 11, 15, 16, 32, 14 + 123456789);
1099 EXPECT_EQ("2017-10-14T14:05:23", absl::FormatCivilTime(cs));
1100 cs = absl::CivilSecond(2013, 11, 15, 16, 32 + 1234567, 14);
1101 EXPECT_EQ("2016-03-22T00:39:14", absl::FormatCivilTime(cs));
1102 cs = absl::CivilSecond(2013, 11, 15, 16 + 123456, 32, 14);
1103 EXPECT_EQ("2027-12-16T16:32:14", absl::FormatCivilTime(cs));
1104 cs = absl::CivilSecond(2013, 11, 15 + 1234, 16, 32, 14);
1105 EXPECT_EQ("2017-04-02T16:32:14", absl::FormatCivilTime(cs));
1106 cs = absl::CivilSecond(2013, 11 + 123, 15, 16, 32, 14);
1107 EXPECT_EQ("2024-02-15T16:32:14", absl::FormatCivilTime(cs));
1108 }
1109
TEST(CivilTime,NormalizeComplexUnderflow)1110 TEST(CivilTime, NormalizeComplexUnderflow) {
1111 absl::CivilSecond cs;
1112 cs = absl::CivilSecond(1999, 3, 0, 0, 0, 0); // year 400
1113 EXPECT_EQ("1999-02-28T00:00:00", absl::FormatCivilTime(cs));
1114 cs = absl::CivilSecond(2013, 11, 15, 16, 32, 14 - 123456789);
1115 EXPECT_EQ("2009-12-17T18:59:05", absl::FormatCivilTime(cs));
1116 cs = absl::CivilSecond(2013, 11, 15, 16, 32 - 1234567, 14);
1117 EXPECT_EQ("2011-07-12T08:25:14", absl::FormatCivilTime(cs));
1118 cs = absl::CivilSecond(2013, 11, 15, 16 - 123456, 32, 14);
1119 EXPECT_EQ("1999-10-16T16:32:14", absl::FormatCivilTime(cs));
1120 cs = absl::CivilSecond(2013, 11, 15 - 1234, 16, 32, 14);
1121 EXPECT_EQ("2010-06-30T16:32:14", absl::FormatCivilTime(cs));
1122 cs = absl::CivilSecond(2013, 11 - 123, 15, 16, 32, 14);
1123 EXPECT_EQ("2003-08-15T16:32:14", absl::FormatCivilTime(cs));
1124 }
1125
TEST(CivilTime,NormalizeMishmash)1126 TEST(CivilTime, NormalizeMishmash) {
1127 absl::CivilSecond cs;
1128 cs = absl::CivilSecond(2013, 11 - 123, 15 + 1234, 16 - 123456, 32 + 1234567,
1129 14 - 123456789);
1130 EXPECT_EQ("1991-05-09T03:06:05", absl::FormatCivilTime(cs));
1131 cs = absl::CivilSecond(2013, 11 + 123, 15 - 1234, 16 + 123456, 32 - 1234567,
1132 14 + 123456789);
1133 EXPECT_EQ("2036-05-24T05:58:23", absl::FormatCivilTime(cs));
1134
1135 cs = absl::CivilSecond(2013, 11, -146097 + 1, 16, 32, 14);
1136 EXPECT_EQ("1613-11-01T16:32:14", absl::FormatCivilTime(cs));
1137 cs = absl::CivilSecond(2013, 11 + 400 * 12, -146097 + 1, 16, 32, 14);
1138 EXPECT_EQ("2013-11-01T16:32:14", absl::FormatCivilTime(cs));
1139 }
1140
1141 // Convert all the days from 1970-1-1 to 1970-1-146097 (aka 2369-12-31)
1142 // and check that they normalize to the expected time. 146097 days span
1143 // the 400-year Gregorian cycle used during normalization.
TEST(CivilTime,NormalizeAllTheDays)1144 TEST(CivilTime, NormalizeAllTheDays) {
1145 absl::CivilDay expected(1970, 1, 1);
1146 for (int day = 1; day <= 146097; ++day) {
1147 absl::CivilSecond cs(1970, 1, day, 0, 0, 0);
1148 EXPECT_EQ(expected, cs);
1149 ++expected;
1150 }
1151 }
1152
TEST(CivilTime,NormalizeWithHugeYear)1153 TEST(CivilTime, NormalizeWithHugeYear) {
1154 absl::CivilMonth c(9223372036854775807, 1);
1155 EXPECT_EQ("9223372036854775807-01", absl::FormatCivilTime(c));
1156 c = c - 1; // Causes normalization
1157 EXPECT_EQ("9223372036854775806-12", absl::FormatCivilTime(c));
1158
1159 c = absl::CivilMonth(-9223372036854775807 - 1, 1);
1160 EXPECT_EQ("-9223372036854775808-01", absl::FormatCivilTime(c));
1161 c = c + 12; // Causes normalization
1162 EXPECT_EQ("-9223372036854775807-01", absl::FormatCivilTime(c));
1163 }
1164
TEST(CivilTime,LeapYears)1165 TEST(CivilTime, LeapYears) {
1166 const absl::CivilSecond s1(2013, 2, 28 + 1, 0, 0, 0);
1167 EXPECT_EQ("2013-03-01T00:00:00", absl::FormatCivilTime(s1));
1168
1169 const absl::CivilSecond s2(2012, 2, 28 + 1, 0, 0, 0);
1170 EXPECT_EQ("2012-02-29T00:00:00", absl::FormatCivilTime(s2));
1171
1172 const absl::CivilSecond s3(1900, 2, 28 + 1, 0, 0, 0);
1173 EXPECT_EQ("1900-03-01T00:00:00", absl::FormatCivilTime(s3));
1174
1175 const struct {
1176 int year;
1177 int days;
1178 struct {
1179 int month;
1180 int day;
1181 } leap_day; // The date of the day after Feb 28.
1182 } kLeapYearTable[]{
1183 {1900, 365, {3, 1}},
1184 {1999, 365, {3, 1}},
1185 {2000, 366, {2, 29}}, // leap year
1186 {2001, 365, {3, 1}},
1187 {2002, 365, {3, 1}},
1188 {2003, 365, {3, 1}},
1189 {2004, 366, {2, 29}}, // leap year
1190 {2005, 365, {3, 1}},
1191 {2006, 365, {3, 1}},
1192 {2007, 365, {3, 1}},
1193 {2008, 366, {2, 29}}, // leap year
1194 {2009, 365, {3, 1}},
1195 {2100, 365, {3, 1}},
1196 };
1197
1198 for (int i = 0; i < ABSL_ARRAYSIZE(kLeapYearTable); ++i) {
1199 const int y = kLeapYearTable[i].year;
1200 const int m = kLeapYearTable[i].leap_day.month;
1201 const int d = kLeapYearTable[i].leap_day.day;
1202 const int n = kLeapYearTable[i].days;
1203
1204 // Tests incrementing through the leap day.
1205 const absl::CivilDay feb28(y, 2, 28);
1206 const absl::CivilDay next_day = feb28 + 1;
1207 EXPECT_EQ(m, next_day.month());
1208 EXPECT_EQ(d, next_day.day());
1209
1210 // Tests difference in days of leap years.
1211 const absl::CivilYear year(feb28);
1212 const absl::CivilYear next_year = year + 1;
1213 EXPECT_EQ(n, absl::CivilDay(next_year) - absl::CivilDay(year));
1214 }
1215 }
1216
TEST(CivilTime,FirstThursdayInMonth)1217 TEST(CivilTime, FirstThursdayInMonth) {
1218 const absl::CivilDay nov1(2014, 11, 1);
1219 const absl::CivilDay thursday =
1220 absl::NextWeekday(nov1 - 1, absl::Weekday::thursday);
1221 EXPECT_EQ("2014-11-06", absl::FormatCivilTime(thursday));
1222
1223 // Bonus: Date of Thanksgiving in the United States
1224 // Rule: Fourth Thursday of November
1225 const absl::CivilDay thanksgiving = thursday + 7 * 3;
1226 EXPECT_EQ("2014-11-27", absl::FormatCivilTime(thanksgiving));
1227 }
1228
TEST(CivilTime,DocumentationExample)1229 TEST(CivilTime, DocumentationExample) {
1230 absl::CivilSecond second(2015, 6, 28, 1, 2, 3); // 2015-06-28 01:02:03
1231 absl::CivilMinute minute(second); // 2015-06-28 01:02:00
1232 absl::CivilDay day(minute); // 2015-06-28 00:00:00
1233
1234 second -= 1; // 2015-06-28 01:02:02
1235 --second; // 2015-06-28 01:02:01
1236 EXPECT_EQ(minute, second - 1); // Comparison between types
1237 EXPECT_LT(minute, second);
1238
1239 // int diff = second - minute; // ERROR: Mixed types, won't compile
1240
1241 absl::CivilDay june_1(2015, 6, 1); // Pass fields to c'tor.
1242 int diff = day - june_1; // Num days between 'day' and June 1
1243 EXPECT_EQ(27, diff);
1244
1245 // Fields smaller than alignment are floored to their minimum value.
1246 absl::CivilDay day_floor(2015, 1, 2, 9, 9, 9);
1247 EXPECT_EQ(0, day_floor.hour()); // 09:09:09 is floored
1248 EXPECT_EQ(absl::CivilDay(2015, 1, 2), day_floor);
1249
1250 // Unspecified fields default to their minimum value
1251 absl::CivilDay day_default(2015); // Defaults to Jan 1
1252 EXPECT_EQ(absl::CivilDay(2015, 1, 1), day_default);
1253
1254 // Iterates all the days of June.
1255 absl::CivilMonth june(day); // CivilDay -> CivilMonth
1256 absl::CivilMonth july = june + 1;
1257 for (absl::CivilDay day = june_1; day < july; ++day) {
1258 // ...
1259 }
1260 }
1261
1262 } // namespace
1263