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