1 // Copyright 2016 Google Inc. All Rights Reserved.
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 <chrono>
16 #include <cstdint>
17 #include <iomanip>
18 #include <sstream>
19 #include <string>
20 
21 #include "absl/base/config.h"
22 #include "absl/time/internal/cctz/include/cctz/time_zone.h"
23 #if defined(__linux__)
24 #include <features.h>
25 #endif
26 
27 #include "gmock/gmock.h"
28 #include "gtest/gtest.h"
29 #include "absl/time/internal/cctz/include/cctz/civil_time.h"
30 
31 namespace chrono = std::chrono;
32 
33 namespace absl {
34 ABSL_NAMESPACE_BEGIN
35 namespace time_internal {
36 namespace cctz {
37 
38 namespace {
39 
40 // This helper is a macro so that failed expectations show up with the
41 // correct line numbers.
42 #define ExpectTime(tp, tz, y, m, d, hh, mm, ss, off, isdst, zone) \
43   do {                                                            \
44     time_zone::absolute_lookup al = tz.lookup(tp);                \
45     EXPECT_EQ(y, al.cs.year());                                   \
46     EXPECT_EQ(m, al.cs.month());                                  \
47     EXPECT_EQ(d, al.cs.day());                                    \
48     EXPECT_EQ(hh, al.cs.hour());                                  \
49     EXPECT_EQ(mm, al.cs.minute());                                \
50     EXPECT_EQ(ss, al.cs.second());                                \
51     EXPECT_EQ(off, al.offset);                                    \
52     EXPECT_TRUE(isdst == al.is_dst);                              \
53     EXPECT_STREQ(zone, al.abbr);                                  \
54   } while (0)
55 
56 const char RFC3339_full[] = "%Y-%m-%d%ET%H:%M:%E*S%Ez";
57 const char RFC3339_sec[] = "%Y-%m-%d%ET%H:%M:%S%Ez";
58 
59 const char RFC1123_full[] = "%a, %d %b %Y %H:%M:%S %z";
60 const char RFC1123_no_wday[] = "%d %b %Y %H:%M:%S %z";
61 
62 // A helper that tests the given format specifier by itself, and with leading
63 // and trailing characters.  For example: TestFormatSpecifier(tp, "%a", "Thu").
64 template <typename D>
TestFormatSpecifier(time_point<D> tp,time_zone tz,const std::string & fmt,const std::string & ans)65 void TestFormatSpecifier(time_point<D> tp, time_zone tz, const std::string& fmt,
66                          const std::string& ans) {
67   EXPECT_EQ(ans, format(fmt, tp, tz)) << fmt;
68   EXPECT_EQ("xxx " + ans, format("xxx " + fmt, tp, tz));
69   EXPECT_EQ(ans + " yyy", format(fmt + " yyy", tp, tz));
70   EXPECT_EQ("xxx " + ans + " yyy", format("xxx " + fmt + " yyy", tp, tz));
71 }
72 
73 }  // namespace
74 
75 //
76 // Testing format()
77 //
78 
TEST(Format,TimePointResolution)79 TEST(Format, TimePointResolution) {
80   const char kFmt[] = "%H:%M:%E*S";
81   const time_zone utc = utc_time_zone();
82   const time_point<chrono::nanoseconds> t0 =
83       chrono::system_clock::from_time_t(1420167845) +
84       chrono::milliseconds(123) + chrono::microseconds(456) +
85       chrono::nanoseconds(789);
86   EXPECT_EQ(
87       "03:04:05.123456789",
88       format(kFmt, chrono::time_point_cast<chrono::nanoseconds>(t0), utc));
89   EXPECT_EQ(
90       "03:04:05.123456",
91       format(kFmt, chrono::time_point_cast<chrono::microseconds>(t0), utc));
92   EXPECT_EQ(
93       "03:04:05.123",
94       format(kFmt, chrono::time_point_cast<chrono::milliseconds>(t0), utc));
95   EXPECT_EQ("03:04:05",
96             format(kFmt, chrono::time_point_cast<chrono::seconds>(t0), utc));
97   EXPECT_EQ(
98       "03:04:05",
99       format(kFmt,
100              chrono::time_point_cast<absl::time_internal::cctz::seconds>(t0),
101              utc));
102   EXPECT_EQ("03:04:00",
103             format(kFmt, chrono::time_point_cast<chrono::minutes>(t0), utc));
104   EXPECT_EQ("03:00:00",
105             format(kFmt, chrono::time_point_cast<chrono::hours>(t0), utc));
106 }
107 
TEST(Format,TimePointExtendedResolution)108 TEST(Format, TimePointExtendedResolution) {
109   const char kFmt[] = "%H:%M:%E*S";
110   const time_zone utc = utc_time_zone();
111   const time_point<absl::time_internal::cctz::seconds> tp =
112       chrono::time_point_cast<absl::time_internal::cctz::seconds>(
113           chrono::system_clock::from_time_t(0)) +
114       chrono::hours(12) + chrono::minutes(34) + chrono::seconds(56);
115 
116   EXPECT_EQ(
117       "12:34:56.123456789012345",
118       detail::format(kFmt, tp, detail::femtoseconds(123456789012345), utc));
119   EXPECT_EQ(
120       "12:34:56.012345678901234",
121       detail::format(kFmt, tp, detail::femtoseconds(12345678901234), utc));
122   EXPECT_EQ("12:34:56.001234567890123",
123             detail::format(kFmt, tp, detail::femtoseconds(1234567890123), utc));
124   EXPECT_EQ("12:34:56.000123456789012",
125             detail::format(kFmt, tp, detail::femtoseconds(123456789012), utc));
126 
127   EXPECT_EQ("12:34:56.000000000000123",
128             detail::format(kFmt, tp, detail::femtoseconds(123), utc));
129   EXPECT_EQ("12:34:56.000000000000012",
130             detail::format(kFmt, tp, detail::femtoseconds(12), utc));
131   EXPECT_EQ("12:34:56.000000000000001",
132             detail::format(kFmt, tp, detail::femtoseconds(1), utc));
133 }
134 
TEST(Format,Basics)135 TEST(Format, Basics) {
136   time_zone tz = utc_time_zone();
137   time_point<chrono::nanoseconds> tp = chrono::system_clock::from_time_t(0);
138 
139   // Starts with a couple basic edge cases.
140   EXPECT_EQ("", format("", tp, tz));
141   EXPECT_EQ(" ", format(" ", tp, tz));
142   EXPECT_EQ("  ", format("  ", tp, tz));
143   EXPECT_EQ("xxx", format("xxx", tp, tz));
144   std::string big(128, 'x');
145   EXPECT_EQ(big, format(big, tp, tz));
146   // Cause the 1024-byte buffer to grow.
147   std::string bigger(100000, 'x');
148   EXPECT_EQ(bigger, format(bigger, tp, tz));
149 
150   tp += chrono::hours(13) + chrono::minutes(4) + chrono::seconds(5);
151   tp += chrono::milliseconds(6) + chrono::microseconds(7) +
152         chrono::nanoseconds(8);
153   EXPECT_EQ("1970-01-01", format("%Y-%m-%d", tp, tz));
154   EXPECT_EQ("13:04:05", format("%H:%M:%S", tp, tz));
155   EXPECT_EQ("13:04:05.006", format("%H:%M:%E3S", tp, tz));
156   EXPECT_EQ("13:04:05.006007", format("%H:%M:%E6S", tp, tz));
157   EXPECT_EQ("13:04:05.006007008", format("%H:%M:%E9S", tp, tz));
158 }
159 
TEST(Format,PosixConversions)160 TEST(Format, PosixConversions) {
161   const time_zone tz = utc_time_zone();
162   auto tp = chrono::system_clock::from_time_t(0);
163 
164   TestFormatSpecifier(tp, tz, "%d", "01");
165   TestFormatSpecifier(tp, tz, "%e", " 1");  // extension but internal support
166   TestFormatSpecifier(tp, tz, "%H", "00");
167   TestFormatSpecifier(tp, tz, "%I", "12");
168   TestFormatSpecifier(tp, tz, "%j", "001");
169   TestFormatSpecifier(tp, tz, "%m", "01");
170   TestFormatSpecifier(tp, tz, "%M", "00");
171   TestFormatSpecifier(tp, tz, "%S", "00");
172   TestFormatSpecifier(tp, tz, "%U", "00");
173 #if !defined(__EMSCRIPTEN__)
174   TestFormatSpecifier(tp, tz, "%w", "4");  // 4=Thursday
175 #endif
176   TestFormatSpecifier(tp, tz, "%W", "00");
177   TestFormatSpecifier(tp, tz, "%y", "70");
178   TestFormatSpecifier(tp, tz, "%Y", "1970");
179   TestFormatSpecifier(tp, tz, "%z", "+0000");
180   TestFormatSpecifier(tp, tz, "%Z", "UTC");
181   TestFormatSpecifier(tp, tz, "%%", "%");
182 
183 #if defined(__linux__)
184   // SU/C99/TZ extensions
185   TestFormatSpecifier(tp, tz, "%C", "19");
186   TestFormatSpecifier(tp, tz, "%D", "01/01/70");
187   TestFormatSpecifier(tp, tz, "%F", "1970-01-01");
188   TestFormatSpecifier(tp, tz, "%g", "70");
189   TestFormatSpecifier(tp, tz, "%G", "1970");
190 #if defined(__GLIBC__)
191   TestFormatSpecifier(tp, tz, "%k", " 0");
192   TestFormatSpecifier(tp, tz, "%l", "12");
193 #endif
194   TestFormatSpecifier(tp, tz, "%n", "\n");
195   TestFormatSpecifier(tp, tz, "%R", "00:00");
196   TestFormatSpecifier(tp, tz, "%t", "\t");
197   TestFormatSpecifier(tp, tz, "%T", "00:00:00");
198   TestFormatSpecifier(tp, tz, "%u", "4");  // 4=Thursday
199   TestFormatSpecifier(tp, tz, "%V", "01");
200   TestFormatSpecifier(tp, tz, "%s", "0");
201 #endif
202 }
203 
TEST(Format,LocaleSpecific)204 TEST(Format, LocaleSpecific) {
205   const time_zone tz = utc_time_zone();
206   auto tp = chrono::system_clock::from_time_t(0);
207 
208   TestFormatSpecifier(tp, tz, "%a", "Thu");
209   TestFormatSpecifier(tp, tz, "%A", "Thursday");
210   TestFormatSpecifier(tp, tz, "%b", "Jan");
211   TestFormatSpecifier(tp, tz, "%B", "January");
212 
213   // %c should at least produce the numeric year and time-of-day.
214   const std::string s = format("%c", tp, utc_time_zone());
215   EXPECT_THAT(s, testing::HasSubstr("1970"));
216   EXPECT_THAT(s, testing::HasSubstr("00:00:00"));
217 
218   TestFormatSpecifier(tp, tz, "%p", "AM");
219   TestFormatSpecifier(tp, tz, "%x", "01/01/70");
220   TestFormatSpecifier(tp, tz, "%X", "00:00:00");
221 
222 #if defined(__linux__)
223   // SU/C99/TZ extensions
224   TestFormatSpecifier(tp, tz, "%h", "Jan");  // Same as %b
225 #if defined(__GLIBC__)
226   TestFormatSpecifier(tp, tz, "%P", "am");
227 #endif
228   TestFormatSpecifier(tp, tz, "%r", "12:00:00 AM");
229 
230   // Modified conversion specifiers %E_
231   TestFormatSpecifier(tp, tz, "%Ec", "Thu Jan  1 00:00:00 1970");
232   TestFormatSpecifier(tp, tz, "%EC", "19");
233   TestFormatSpecifier(tp, tz, "%Ex", "01/01/70");
234   TestFormatSpecifier(tp, tz, "%EX", "00:00:00");
235   TestFormatSpecifier(tp, tz, "%Ey", "70");
236   TestFormatSpecifier(tp, tz, "%EY", "1970");
237 
238   // Modified conversion specifiers %O_
239   TestFormatSpecifier(tp, tz, "%Od", "01");
240   TestFormatSpecifier(tp, tz, "%Oe", " 1");
241   TestFormatSpecifier(tp, tz, "%OH", "00");
242   TestFormatSpecifier(tp, tz, "%OI", "12");
243   TestFormatSpecifier(tp, tz, "%Om", "01");
244   TestFormatSpecifier(tp, tz, "%OM", "00");
245   TestFormatSpecifier(tp, tz, "%OS", "00");
246   TestFormatSpecifier(tp, tz, "%Ou", "4");  // 4=Thursday
247   TestFormatSpecifier(tp, tz, "%OU", "00");
248   TestFormatSpecifier(tp, tz, "%OV", "01");
249   TestFormatSpecifier(tp, tz, "%Ow", "4");  // 4=Thursday
250   TestFormatSpecifier(tp, tz, "%OW", "00");
251   TestFormatSpecifier(tp, tz, "%Oy", "70");
252 #endif
253 }
254 
TEST(Format,Escaping)255 TEST(Format, Escaping) {
256   const time_zone tz = utc_time_zone();
257   auto tp = chrono::system_clock::from_time_t(0);
258 
259   TestFormatSpecifier(tp, tz, "%%", "%");
260   TestFormatSpecifier(tp, tz, "%%a", "%a");
261   TestFormatSpecifier(tp, tz, "%%b", "%b");
262   TestFormatSpecifier(tp, tz, "%%Ea", "%Ea");
263   TestFormatSpecifier(tp, tz, "%%Es", "%Es");
264   TestFormatSpecifier(tp, tz, "%%E3S", "%E3S");
265   TestFormatSpecifier(tp, tz, "%%OS", "%OS");
266   TestFormatSpecifier(tp, tz, "%%O3S", "%O3S");
267 
268   // Multiple levels of escaping.
269   TestFormatSpecifier(tp, tz, "%%%Y", "%1970");
270   TestFormatSpecifier(tp, tz, "%%%E3S", "%00.000");
271   TestFormatSpecifier(tp, tz, "%%%%E3S", "%%E3S");
272 }
273 
TEST(Format,ExtendedSeconds)274 TEST(Format, ExtendedSeconds) {
275   const time_zone tz = utc_time_zone();
276 
277   // No subseconds.
278   time_point<chrono::nanoseconds> tp = chrono::system_clock::from_time_t(0);
279   tp += chrono::seconds(5);
280   EXPECT_EQ("05", format("%E*S", tp, tz));
281   EXPECT_EQ("05", format("%E0S", tp, tz));
282   EXPECT_EQ("05.0", format("%E1S", tp, tz));
283   EXPECT_EQ("05.00", format("%E2S", tp, tz));
284   EXPECT_EQ("05.000", format("%E3S", tp, tz));
285   EXPECT_EQ("05.0000", format("%E4S", tp, tz));
286   EXPECT_EQ("05.00000", format("%E5S", tp, tz));
287   EXPECT_EQ("05.000000", format("%E6S", tp, tz));
288   EXPECT_EQ("05.0000000", format("%E7S", tp, tz));
289   EXPECT_EQ("05.00000000", format("%E8S", tp, tz));
290   EXPECT_EQ("05.000000000", format("%E9S", tp, tz));
291   EXPECT_EQ("05.0000000000", format("%E10S", tp, tz));
292   EXPECT_EQ("05.00000000000", format("%E11S", tp, tz));
293   EXPECT_EQ("05.000000000000", format("%E12S", tp, tz));
294   EXPECT_EQ("05.0000000000000", format("%E13S", tp, tz));
295   EXPECT_EQ("05.00000000000000", format("%E14S", tp, tz));
296   EXPECT_EQ("05.000000000000000", format("%E15S", tp, tz));
297 
298   // With subseconds.
299   tp += chrono::milliseconds(6) + chrono::microseconds(7) +
300         chrono::nanoseconds(8);
301   EXPECT_EQ("05.006007008", format("%E*S", tp, tz));
302   EXPECT_EQ("05", format("%E0S", tp, tz));
303   EXPECT_EQ("05.0", format("%E1S", tp, tz));
304   EXPECT_EQ("05.00", format("%E2S", tp, tz));
305   EXPECT_EQ("05.006", format("%E3S", tp, tz));
306   EXPECT_EQ("05.0060", format("%E4S", tp, tz));
307   EXPECT_EQ("05.00600", format("%E5S", tp, tz));
308   EXPECT_EQ("05.006007", format("%E6S", tp, tz));
309   EXPECT_EQ("05.0060070", format("%E7S", tp, tz));
310   EXPECT_EQ("05.00600700", format("%E8S", tp, tz));
311   EXPECT_EQ("05.006007008", format("%E9S", tp, tz));
312   EXPECT_EQ("05.0060070080", format("%E10S", tp, tz));
313   EXPECT_EQ("05.00600700800", format("%E11S", tp, tz));
314   EXPECT_EQ("05.006007008000", format("%E12S", tp, tz));
315   EXPECT_EQ("05.0060070080000", format("%E13S", tp, tz));
316   EXPECT_EQ("05.00600700800000", format("%E14S", tp, tz));
317   EXPECT_EQ("05.006007008000000", format("%E15S", tp, tz));
318 
319   // Times before the Unix epoch.
320   tp = chrono::system_clock::from_time_t(0) + chrono::microseconds(-1);
321   EXPECT_EQ("1969-12-31 23:59:59.999999",
322             format("%Y-%m-%d %H:%M:%E*S", tp, tz));
323 
324   // Here is a "%E*S" case we got wrong for a while.  While the first
325   // instant below is correctly rendered as "...:07.333304", the second
326   // one used to appear as "...:07.33330499999999999".
327   tp = chrono::system_clock::from_time_t(0) +
328        chrono::microseconds(1395024427333304);
329   EXPECT_EQ("2014-03-17 02:47:07.333304",
330             format("%Y-%m-%d %H:%M:%E*S", tp, tz));
331   tp += chrono::microseconds(1);
332   EXPECT_EQ("2014-03-17 02:47:07.333305",
333             format("%Y-%m-%d %H:%M:%E*S", tp, tz));
334 }
335 
TEST(Format,ExtendedSubeconds)336 TEST(Format, ExtendedSubeconds) {
337   const time_zone tz = utc_time_zone();
338 
339   // No subseconds.
340   time_point<chrono::nanoseconds> tp = chrono::system_clock::from_time_t(0);
341   tp += chrono::seconds(5);
342   EXPECT_EQ("0", format("%E*f", tp, tz));
343   EXPECT_EQ("", format("%E0f", tp, tz));
344   EXPECT_EQ("0", format("%E1f", tp, tz));
345   EXPECT_EQ("00", format("%E2f", tp, tz));
346   EXPECT_EQ("000", format("%E3f", tp, tz));
347   EXPECT_EQ("0000", format("%E4f", tp, tz));
348   EXPECT_EQ("00000", format("%E5f", tp, tz));
349   EXPECT_EQ("000000", format("%E6f", tp, tz));
350   EXPECT_EQ("0000000", format("%E7f", tp, tz));
351   EXPECT_EQ("00000000", format("%E8f", tp, tz));
352   EXPECT_EQ("000000000", format("%E9f", tp, tz));
353   EXPECT_EQ("0000000000", format("%E10f", tp, tz));
354   EXPECT_EQ("00000000000", format("%E11f", tp, tz));
355   EXPECT_EQ("000000000000", format("%E12f", tp, tz));
356   EXPECT_EQ("0000000000000", format("%E13f", tp, tz));
357   EXPECT_EQ("00000000000000", format("%E14f", tp, tz));
358   EXPECT_EQ("000000000000000", format("%E15f", tp, tz));
359 
360   // With subseconds.
361   tp += chrono::milliseconds(6) + chrono::microseconds(7) +
362         chrono::nanoseconds(8);
363   EXPECT_EQ("006007008", format("%E*f", tp, tz));
364   EXPECT_EQ("", format("%E0f", tp, tz));
365   EXPECT_EQ("0", format("%E1f", tp, tz));
366   EXPECT_EQ("00", format("%E2f", tp, tz));
367   EXPECT_EQ("006", format("%E3f", tp, tz));
368   EXPECT_EQ("0060", format("%E4f", tp, tz));
369   EXPECT_EQ("00600", format("%E5f", tp, tz));
370   EXPECT_EQ("006007", format("%E6f", tp, tz));
371   EXPECT_EQ("0060070", format("%E7f", tp, tz));
372   EXPECT_EQ("00600700", format("%E8f", tp, tz));
373   EXPECT_EQ("006007008", format("%E9f", tp, tz));
374   EXPECT_EQ("0060070080", format("%E10f", tp, tz));
375   EXPECT_EQ("00600700800", format("%E11f", tp, tz));
376   EXPECT_EQ("006007008000", format("%E12f", tp, tz));
377   EXPECT_EQ("0060070080000", format("%E13f", tp, tz));
378   EXPECT_EQ("00600700800000", format("%E14f", tp, tz));
379   EXPECT_EQ("006007008000000", format("%E15f", tp, tz));
380 
381   // Times before the Unix epoch.
382   tp = chrono::system_clock::from_time_t(0) + chrono::microseconds(-1);
383   EXPECT_EQ("1969-12-31 23:59:59.999999",
384             format("%Y-%m-%d %H:%M:%S.%E*f", tp, tz));
385 
386   // Here is a "%E*S" case we got wrong for a while.  While the first
387   // instant below is correctly rendered as "...:07.333304", the second
388   // one used to appear as "...:07.33330499999999999".
389   tp = chrono::system_clock::from_time_t(0) +
390        chrono::microseconds(1395024427333304);
391   EXPECT_EQ("2014-03-17 02:47:07.333304",
392             format("%Y-%m-%d %H:%M:%S.%E*f", tp, tz));
393   tp += chrono::microseconds(1);
394   EXPECT_EQ("2014-03-17 02:47:07.333305",
395             format("%Y-%m-%d %H:%M:%S.%E*f", tp, tz));
396 }
397 
TEST(Format,CompareExtendSecondsVsSubseconds)398 TEST(Format, CompareExtendSecondsVsSubseconds) {
399   const time_zone tz = utc_time_zone();
400 
401   // This test case illustrates the differences/similarities between:
402   //   fmt_A: %E<prec>S
403   //   fmt_B: %S.%E<prec>f
404   auto fmt_A = [](const std::string& prec) { return "%E" + prec + "S"; };
405   auto fmt_B = [](const std::string& prec) { return "%S.%E" + prec + "f"; };
406 
407   // No subseconds:
408   time_point<chrono::nanoseconds> tp = chrono::system_clock::from_time_t(0);
409   tp += chrono::seconds(5);
410   // ... %E*S and %S.%E*f are different.
411   EXPECT_EQ("05", format(fmt_A("*"), tp, tz));
412   EXPECT_EQ("05.0", format(fmt_B("*"), tp, tz));
413   // ... %E0S and %S.%E0f are different.
414   EXPECT_EQ("05", format(fmt_A("0"), tp, tz));
415   EXPECT_EQ("05.", format(fmt_B("0"), tp, tz));
416   // ... %E<prec>S and %S.%E<prec>f are the same for prec in [1:15].
417   for (int prec = 1; prec <= 15; ++prec) {
418     const std::string a = format(fmt_A(std::to_string(prec)), tp, tz);
419     const std::string b = format(fmt_B(std::to_string(prec)), tp, tz);
420     EXPECT_EQ(a, b) << "prec=" << prec;
421   }
422 
423   // With subseconds:
424   // ... %E*S and %S.%E*f are the same.
425   tp += chrono::milliseconds(6) + chrono::microseconds(7) +
426         chrono::nanoseconds(8);
427   EXPECT_EQ("05.006007008", format(fmt_A("*"), tp, tz));
428   EXPECT_EQ("05.006007008", format(fmt_B("*"), tp, tz));
429   // ... %E0S and %S.%E0f are different.
430   EXPECT_EQ("05", format(fmt_A("0"), tp, tz));
431   EXPECT_EQ("05.", format(fmt_B("0"), tp, tz));
432   // ... %E<prec>S and %S.%E<prec>f are the same for prec in [1:15].
433   for (int prec = 1; prec <= 15; ++prec) {
434     const std::string a = format(fmt_A(std::to_string(prec)), tp, tz);
435     const std::string b = format(fmt_B(std::to_string(prec)), tp, tz);
436     EXPECT_EQ(a, b) << "prec=" << prec;
437   }
438 }
439 
TEST(Format,ExtendedOffset)440 TEST(Format, ExtendedOffset) {
441   const auto tp = chrono::system_clock::from_time_t(0);
442 
443   auto tz = fixed_time_zone(absl::time_internal::cctz::seconds::zero());
444   TestFormatSpecifier(tp, tz, "%z", "+0000");
445   TestFormatSpecifier(tp, tz, "%:z", "+00:00");
446   TestFormatSpecifier(tp, tz, "%Ez", "+00:00");
447 
448   tz = fixed_time_zone(chrono::seconds(56));
449   TestFormatSpecifier(tp, tz, "%z", "+0000");
450   TestFormatSpecifier(tp, tz, "%:z", "+00:00");
451   TestFormatSpecifier(tp, tz, "%Ez", "+00:00");
452 
453   tz = fixed_time_zone(-chrono::seconds(56));  // NOTE: +00:00
454   TestFormatSpecifier(tp, tz, "%z", "+0000");
455   TestFormatSpecifier(tp, tz, "%:z", "+00:00");
456   TestFormatSpecifier(tp, tz, "%Ez", "+00:00");
457 
458   tz = fixed_time_zone(chrono::minutes(34));
459   TestFormatSpecifier(tp, tz, "%z", "+0034");
460   TestFormatSpecifier(tp, tz, "%:z", "+00:34");
461   TestFormatSpecifier(tp, tz, "%Ez", "+00:34");
462 
463   tz = fixed_time_zone(-chrono::minutes(34));
464   TestFormatSpecifier(tp, tz, "%z", "-0034");
465   TestFormatSpecifier(tp, tz, "%:z", "-00:34");
466   TestFormatSpecifier(tp, tz, "%Ez", "-00:34");
467 
468   tz = fixed_time_zone(chrono::minutes(34) + chrono::seconds(56));
469   TestFormatSpecifier(tp, tz, "%z", "+0034");
470   TestFormatSpecifier(tp, tz, "%:z", "+00:34");
471   TestFormatSpecifier(tp, tz, "%Ez", "+00:34");
472 
473   tz = fixed_time_zone(-chrono::minutes(34) - chrono::seconds(56));
474   TestFormatSpecifier(tp, tz, "%z", "-0034");
475   TestFormatSpecifier(tp, tz, "%:z", "-00:34");
476   TestFormatSpecifier(tp, tz, "%Ez", "-00:34");
477 
478   tz = fixed_time_zone(chrono::hours(12));
479   TestFormatSpecifier(tp, tz, "%z", "+1200");
480   TestFormatSpecifier(tp, tz, "%:z", "+12:00");
481   TestFormatSpecifier(tp, tz, "%Ez", "+12:00");
482 
483   tz = fixed_time_zone(-chrono::hours(12));
484   TestFormatSpecifier(tp, tz, "%z", "-1200");
485   TestFormatSpecifier(tp, tz, "%:z", "-12:00");
486   TestFormatSpecifier(tp, tz, "%Ez", "-12:00");
487 
488   tz = fixed_time_zone(chrono::hours(12) + chrono::seconds(56));
489   TestFormatSpecifier(tp, tz, "%z", "+1200");
490   TestFormatSpecifier(tp, tz, "%:z", "+12:00");
491   TestFormatSpecifier(tp, tz, "%Ez", "+12:00");
492 
493   tz = fixed_time_zone(-chrono::hours(12) - chrono::seconds(56));
494   TestFormatSpecifier(tp, tz, "%z", "-1200");
495   TestFormatSpecifier(tp, tz, "%:z", "-12:00");
496   TestFormatSpecifier(tp, tz, "%Ez", "-12:00");
497 
498   tz = fixed_time_zone(chrono::hours(12) + chrono::minutes(34));
499   TestFormatSpecifier(tp, tz, "%z", "+1234");
500   TestFormatSpecifier(tp, tz, "%:z", "+12:34");
501   TestFormatSpecifier(tp, tz, "%Ez", "+12:34");
502 
503   tz = fixed_time_zone(-chrono::hours(12) - chrono::minutes(34));
504   TestFormatSpecifier(tp, tz, "%z", "-1234");
505   TestFormatSpecifier(tp, tz, "%:z", "-12:34");
506   TestFormatSpecifier(tp, tz, "%Ez", "-12:34");
507 
508   tz = fixed_time_zone(chrono::hours(12) + chrono::minutes(34) +
509                        chrono::seconds(56));
510   TestFormatSpecifier(tp, tz, "%z", "+1234");
511   TestFormatSpecifier(tp, tz, "%:z", "+12:34");
512   TestFormatSpecifier(tp, tz, "%Ez", "+12:34");
513 
514   tz = fixed_time_zone(-chrono::hours(12) - chrono::minutes(34) -
515                        chrono::seconds(56));
516   TestFormatSpecifier(tp, tz, "%z", "-1234");
517   TestFormatSpecifier(tp, tz, "%:z", "-12:34");
518   TestFormatSpecifier(tp, tz, "%Ez", "-12:34");
519 }
520 
TEST(Format,ExtendedSecondOffset)521 TEST(Format, ExtendedSecondOffset) {
522   const auto tp = chrono::system_clock::from_time_t(0);
523 
524   auto tz = fixed_time_zone(absl::time_internal::cctz::seconds::zero());
525   TestFormatSpecifier(tp, tz, "%E*z", "+00:00:00");
526   TestFormatSpecifier(tp, tz, "%::z", "+00:00:00");
527   TestFormatSpecifier(tp, tz, "%:::z", "+00");
528 
529   tz = fixed_time_zone(chrono::seconds(56));
530   TestFormatSpecifier(tp, tz, "%E*z", "+00:00:56");
531   TestFormatSpecifier(tp, tz, "%::z", "+00:00:56");
532   TestFormatSpecifier(tp, tz, "%:::z", "+00:00:56");
533 
534   tz = fixed_time_zone(-chrono::seconds(56));
535   TestFormatSpecifier(tp, tz, "%E*z", "-00:00:56");
536   TestFormatSpecifier(tp, tz, "%::z", "-00:00:56");
537   TestFormatSpecifier(tp, tz, "%:::z", "-00:00:56");
538 
539   tz = fixed_time_zone(chrono::minutes(34));
540   TestFormatSpecifier(tp, tz, "%E*z", "+00:34:00");
541   TestFormatSpecifier(tp, tz, "%::z", "+00:34:00");
542   TestFormatSpecifier(tp, tz, "%:::z", "+00:34");
543 
544   tz = fixed_time_zone(-chrono::minutes(34));
545   TestFormatSpecifier(tp, tz, "%E*z", "-00:34:00");
546   TestFormatSpecifier(tp, tz, "%::z", "-00:34:00");
547   TestFormatSpecifier(tp, tz, "%:::z", "-00:34");
548 
549   tz = fixed_time_zone(chrono::minutes(34) + chrono::seconds(56));
550   TestFormatSpecifier(tp, tz, "%E*z", "+00:34:56");
551   TestFormatSpecifier(tp, tz, "%::z", "+00:34:56");
552   TestFormatSpecifier(tp, tz, "%:::z", "+00:34:56");
553 
554   tz = fixed_time_zone(-chrono::minutes(34) - chrono::seconds(56));
555   TestFormatSpecifier(tp, tz, "%E*z", "-00:34:56");
556   TestFormatSpecifier(tp, tz, "%::z", "-00:34:56");
557   TestFormatSpecifier(tp, tz, "%:::z", "-00:34:56");
558 
559   tz = fixed_time_zone(chrono::hours(12));
560   TestFormatSpecifier(tp, tz, "%E*z", "+12:00:00");
561   TestFormatSpecifier(tp, tz, "%::z", "+12:00:00");
562   TestFormatSpecifier(tp, tz, "%:::z", "+12");
563 
564   tz = fixed_time_zone(-chrono::hours(12));
565   TestFormatSpecifier(tp, tz, "%E*z", "-12:00:00");
566   TestFormatSpecifier(tp, tz, "%::z", "-12:00:00");
567   TestFormatSpecifier(tp, tz, "%:::z", "-12");
568 
569   tz = fixed_time_zone(chrono::hours(12) + chrono::seconds(56));
570   TestFormatSpecifier(tp, tz, "%E*z", "+12:00:56");
571   TestFormatSpecifier(tp, tz, "%::z", "+12:00:56");
572   TestFormatSpecifier(tp, tz, "%:::z", "+12:00:56");
573 
574   tz = fixed_time_zone(-chrono::hours(12) - chrono::seconds(56));
575   TestFormatSpecifier(tp, tz, "%E*z", "-12:00:56");
576   TestFormatSpecifier(tp, tz, "%::z", "-12:00:56");
577   TestFormatSpecifier(tp, tz, "%:::z", "-12:00:56");
578 
579   tz = fixed_time_zone(chrono::hours(12) + chrono::minutes(34));
580   TestFormatSpecifier(tp, tz, "%E*z", "+12:34:00");
581   TestFormatSpecifier(tp, tz, "%::z", "+12:34:00");
582   TestFormatSpecifier(tp, tz, "%:::z", "+12:34");
583 
584   tz = fixed_time_zone(-chrono::hours(12) - chrono::minutes(34));
585   TestFormatSpecifier(tp, tz, "%E*z", "-12:34:00");
586   TestFormatSpecifier(tp, tz, "%::z", "-12:34:00");
587   TestFormatSpecifier(tp, tz, "%:::z", "-12:34");
588 
589   tz = fixed_time_zone(chrono::hours(12) + chrono::minutes(34) +
590                        chrono::seconds(56));
591   TestFormatSpecifier(tp, tz, "%E*z", "+12:34:56");
592   TestFormatSpecifier(tp, tz, "%::z", "+12:34:56");
593   TestFormatSpecifier(tp, tz, "%:::z", "+12:34:56");
594 
595   tz = fixed_time_zone(-chrono::hours(12) - chrono::minutes(34) -
596                        chrono::seconds(56));
597   TestFormatSpecifier(tp, tz, "%E*z", "-12:34:56");
598   TestFormatSpecifier(tp, tz, "%::z", "-12:34:56");
599   TestFormatSpecifier(tp, tz, "%:::z", "-12:34:56");
600 }
601 
TEST(Format,ExtendedYears)602 TEST(Format, ExtendedYears) {
603   const time_zone utc = utc_time_zone();
604   const char e4y_fmt[] = "%E4Y%m%d";  // no separators
605 
606   // %E4Y zero-pads the year to produce at least 4 chars, including the sign.
607   auto tp = convert(civil_second(-999, 11, 27, 0, 0, 0), utc);
608   EXPECT_EQ("-9991127", format(e4y_fmt, tp, utc));
609   tp = convert(civil_second(-99, 11, 27, 0, 0, 0), utc);
610   EXPECT_EQ("-0991127", format(e4y_fmt, tp, utc));
611   tp = convert(civil_second(-9, 11, 27, 0, 0, 0), utc);
612   EXPECT_EQ("-0091127", format(e4y_fmt, tp, utc));
613   tp = convert(civil_second(-1, 11, 27, 0, 0, 0), utc);
614   EXPECT_EQ("-0011127", format(e4y_fmt, tp, utc));
615   tp = convert(civil_second(0, 11, 27, 0, 0, 0), utc);
616   EXPECT_EQ("00001127", format(e4y_fmt, tp, utc));
617   tp = convert(civil_second(1, 11, 27, 0, 0, 0), utc);
618   EXPECT_EQ("00011127", format(e4y_fmt, tp, utc));
619   tp = convert(civil_second(9, 11, 27, 0, 0, 0), utc);
620   EXPECT_EQ("00091127", format(e4y_fmt, tp, utc));
621   tp = convert(civil_second(99, 11, 27, 0, 0, 0), utc);
622   EXPECT_EQ("00991127", format(e4y_fmt, tp, utc));
623   tp = convert(civil_second(999, 11, 27, 0, 0, 0), utc);
624   EXPECT_EQ("09991127", format(e4y_fmt, tp, utc));
625   tp = convert(civil_second(9999, 11, 27, 0, 0, 0), utc);
626   EXPECT_EQ("99991127", format(e4y_fmt, tp, utc));
627 
628   // When the year is outside [-999:9999], more than 4 chars are produced.
629   tp = convert(civil_second(-1000, 11, 27, 0, 0, 0), utc);
630   EXPECT_EQ("-10001127", format(e4y_fmt, tp, utc));
631   tp = convert(civil_second(10000, 11, 27, 0, 0, 0), utc);
632   EXPECT_EQ("100001127", format(e4y_fmt, tp, utc));
633 }
634 
TEST(Format,RFC3339Format)635 TEST(Format, RFC3339Format) {
636   time_zone tz;
637   EXPECT_TRUE(load_time_zone("America/Los_Angeles", &tz));
638 
639   time_point<chrono::nanoseconds> tp =
640       convert(civil_second(1977, 6, 28, 9, 8, 7), tz);
641   EXPECT_EQ("1977-06-28T09:08:07-07:00", format(RFC3339_full, tp, tz));
642   EXPECT_EQ("1977-06-28T09:08:07-07:00", format(RFC3339_sec, tp, tz));
643 
644   tp += chrono::milliseconds(100);
645   EXPECT_EQ("1977-06-28T09:08:07.1-07:00", format(RFC3339_full, tp, tz));
646   EXPECT_EQ("1977-06-28T09:08:07-07:00", format(RFC3339_sec, tp, tz));
647 
648   tp += chrono::milliseconds(20);
649   EXPECT_EQ("1977-06-28T09:08:07.12-07:00", format(RFC3339_full, tp, tz));
650   EXPECT_EQ("1977-06-28T09:08:07-07:00", format(RFC3339_sec, tp, tz));
651 
652   tp += chrono::milliseconds(3);
653   EXPECT_EQ("1977-06-28T09:08:07.123-07:00", format(RFC3339_full, tp, tz));
654   EXPECT_EQ("1977-06-28T09:08:07-07:00", format(RFC3339_sec, tp, tz));
655 
656   tp += chrono::microseconds(400);
657   EXPECT_EQ("1977-06-28T09:08:07.1234-07:00", format(RFC3339_full, tp, tz));
658   EXPECT_EQ("1977-06-28T09:08:07-07:00", format(RFC3339_sec, tp, tz));
659 
660   tp += chrono::microseconds(50);
661   EXPECT_EQ("1977-06-28T09:08:07.12345-07:00", format(RFC3339_full, tp, tz));
662   EXPECT_EQ("1977-06-28T09:08:07-07:00", format(RFC3339_sec, tp, tz));
663 
664   tp += chrono::microseconds(6);
665   EXPECT_EQ("1977-06-28T09:08:07.123456-07:00", format(RFC3339_full, tp, tz));
666   EXPECT_EQ("1977-06-28T09:08:07-07:00", format(RFC3339_sec, tp, tz));
667 
668   tp += chrono::nanoseconds(700);
669   EXPECT_EQ("1977-06-28T09:08:07.1234567-07:00", format(RFC3339_full, tp, tz));
670   EXPECT_EQ("1977-06-28T09:08:07-07:00", format(RFC3339_sec, tp, tz));
671 
672   tp += chrono::nanoseconds(80);
673   EXPECT_EQ("1977-06-28T09:08:07.12345678-07:00", format(RFC3339_full, tp, tz));
674   EXPECT_EQ("1977-06-28T09:08:07-07:00", format(RFC3339_sec, tp, tz));
675 
676   tp += chrono::nanoseconds(9);
677   EXPECT_EQ("1977-06-28T09:08:07.123456789-07:00",
678             format(RFC3339_full, tp, tz));
679   EXPECT_EQ("1977-06-28T09:08:07-07:00", format(RFC3339_sec, tp, tz));
680 }
681 
TEST(Format,RFC1123Format)682 TEST(Format, RFC1123Format) {  // locale specific
683   time_zone tz;
684   EXPECT_TRUE(load_time_zone("America/Los_Angeles", &tz));
685 
686   auto tp = convert(civil_second(1977, 6, 28, 9, 8, 7), tz);
687   EXPECT_EQ("Tue, 28 Jun 1977 09:08:07 -0700", format(RFC1123_full, tp, tz));
688   EXPECT_EQ("28 Jun 1977 09:08:07 -0700", format(RFC1123_no_wday, tp, tz));
689 }
690 
TEST(Format,Week)691 TEST(Format, Week) {
692   const time_zone utc = utc_time_zone();
693 
694   auto tp = convert(civil_second(2017, 1, 1, 0, 0, 0), utc);
695   EXPECT_EQ("2017-01-7", format("%Y-%U-%u", tp, utc));
696   EXPECT_EQ("2017-00-0", format("%Y-%W-%w", tp, utc));
697 
698   tp = convert(civil_second(2017, 12, 31, 0, 0, 0), utc);
699   EXPECT_EQ("2017-53-7", format("%Y-%U-%u", tp, utc));
700   EXPECT_EQ("2017-52-0", format("%Y-%W-%w", tp, utc));
701 
702   tp = convert(civil_second(2018, 1, 1, 0, 0, 0), utc);
703   EXPECT_EQ("2018-00-1", format("%Y-%U-%u", tp, utc));
704   EXPECT_EQ("2018-01-1", format("%Y-%W-%w", tp, utc));
705 
706   tp = convert(civil_second(2018, 12, 31, 0, 0, 0), utc);
707   EXPECT_EQ("2018-52-1", format("%Y-%U-%u", tp, utc));
708   EXPECT_EQ("2018-53-1", format("%Y-%W-%w", tp, utc));
709 
710   tp = convert(civil_second(2019, 1, 1, 0, 0, 0), utc);
711   EXPECT_EQ("2019-00-2", format("%Y-%U-%u", tp, utc));
712   EXPECT_EQ("2019-00-2", format("%Y-%W-%w", tp, utc));
713 
714   tp = convert(civil_second(2019, 12, 31, 0, 0, 0), utc);
715   EXPECT_EQ("2019-52-2", format("%Y-%U-%u", tp, utc));
716   EXPECT_EQ("2019-52-2", format("%Y-%W-%w", tp, utc));
717 }
718 
719 //
720 // Testing parse()
721 //
722 
TEST(Parse,TimePointResolution)723 TEST(Parse, TimePointResolution) {
724   const char kFmt[] = "%H:%M:%E*S";
725   const time_zone utc = utc_time_zone();
726 
727   time_point<chrono::nanoseconds> tp_ns;
728   EXPECT_TRUE(parse(kFmt, "03:04:05.123456789", utc, &tp_ns));
729   EXPECT_EQ("03:04:05.123456789", format(kFmt, tp_ns, utc));
730   EXPECT_TRUE(parse(kFmt, "03:04:05.123456", utc, &tp_ns));
731   EXPECT_EQ("03:04:05.123456", format(kFmt, tp_ns, utc));
732 
733   time_point<chrono::microseconds> tp_us;
734   EXPECT_TRUE(parse(kFmt, "03:04:05.123456789", utc, &tp_us));
735   EXPECT_EQ("03:04:05.123456", format(kFmt, tp_us, utc));
736   EXPECT_TRUE(parse(kFmt, "03:04:05.123456", utc, &tp_us));
737   EXPECT_EQ("03:04:05.123456", format(kFmt, tp_us, utc));
738   EXPECT_TRUE(parse(kFmt, "03:04:05.123", utc, &tp_us));
739   EXPECT_EQ("03:04:05.123", format(kFmt, tp_us, utc));
740 
741   time_point<chrono::milliseconds> tp_ms;
742   EXPECT_TRUE(parse(kFmt, "03:04:05.123456", utc, &tp_ms));
743   EXPECT_EQ("03:04:05.123", format(kFmt, tp_ms, utc));
744   EXPECT_TRUE(parse(kFmt, "03:04:05.123", utc, &tp_ms));
745   EXPECT_EQ("03:04:05.123", format(kFmt, tp_ms, utc));
746   EXPECT_TRUE(parse(kFmt, "03:04:05", utc, &tp_ms));
747   EXPECT_EQ("03:04:05", format(kFmt, tp_ms, utc));
748 
749   time_point<chrono::seconds> tp_s;
750   EXPECT_TRUE(parse(kFmt, "03:04:05.123", utc, &tp_s));
751   EXPECT_EQ("03:04:05", format(kFmt, tp_s, utc));
752   EXPECT_TRUE(parse(kFmt, "03:04:05", utc, &tp_s));
753   EXPECT_EQ("03:04:05", format(kFmt, tp_s, utc));
754 
755   time_point<chrono::minutes> tp_m;
756   EXPECT_TRUE(parse(kFmt, "03:04:05", utc, &tp_m));
757   EXPECT_EQ("03:04:00", format(kFmt, tp_m, utc));
758 
759   time_point<chrono::hours> tp_h;
760   EXPECT_TRUE(parse(kFmt, "03:04:05", utc, &tp_h));
761   EXPECT_EQ("03:00:00", format(kFmt, tp_h, utc));
762 }
763 
TEST(Parse,TimePointExtendedResolution)764 TEST(Parse, TimePointExtendedResolution) {
765   const char kFmt[] = "%H:%M:%E*S";
766   const time_zone utc = utc_time_zone();
767 
768   time_point<absl::time_internal::cctz::seconds> tp;
769   detail::femtoseconds fs;
770   EXPECT_TRUE(detail::parse(kFmt, "12:34:56.123456789012345", utc, &tp, &fs));
771   EXPECT_EQ("12:34:56.123456789012345", detail::format(kFmt, tp, fs, utc));
772   EXPECT_TRUE(detail::parse(kFmt, "12:34:56.012345678901234", utc, &tp, &fs));
773   EXPECT_EQ("12:34:56.012345678901234", detail::format(kFmt, tp, fs, utc));
774   EXPECT_TRUE(detail::parse(kFmt, "12:34:56.001234567890123", utc, &tp, &fs));
775   EXPECT_EQ("12:34:56.001234567890123", detail::format(kFmt, tp, fs, utc));
776   EXPECT_TRUE(detail::parse(kFmt, "12:34:56.000000000000123", utc, &tp, &fs));
777   EXPECT_EQ("12:34:56.000000000000123", detail::format(kFmt, tp, fs, utc));
778   EXPECT_TRUE(detail::parse(kFmt, "12:34:56.000000000000012", utc, &tp, &fs));
779   EXPECT_EQ("12:34:56.000000000000012", detail::format(kFmt, tp, fs, utc));
780   EXPECT_TRUE(detail::parse(kFmt, "12:34:56.000000000000001", utc, &tp, &fs));
781   EXPECT_EQ("12:34:56.000000000000001", detail::format(kFmt, tp, fs, utc));
782 }
783 
TEST(Parse,Basics)784 TEST(Parse, Basics) {
785   time_zone tz = utc_time_zone();
786   time_point<chrono::nanoseconds> tp =
787       chrono::system_clock::from_time_t(1234567890);
788 
789   // Simple edge cases.
790   EXPECT_TRUE(parse("", "", tz, &tp));
791   EXPECT_EQ(chrono::system_clock::from_time_t(0), tp);  // everything defaulted
792   EXPECT_TRUE(parse(" ", " ", tz, &tp));
793   EXPECT_TRUE(parse("  ", "  ", tz, &tp));
794   EXPECT_TRUE(parse("x", "x", tz, &tp));
795   EXPECT_TRUE(parse("xxx", "xxx", tz, &tp));
796 
797   EXPECT_TRUE(
798       parse("%Y-%m-%d %H:%M:%S %z", "2013-06-28 19:08:09 -0800", tz, &tp));
799   ExpectTime(tp, tz, 2013, 6, 29, 3, 8, 9, 0, false, "UTC");
800 }
801 
TEST(Parse,WithTimeZone)802 TEST(Parse, WithTimeZone) {
803   time_zone tz;
804   EXPECT_TRUE(load_time_zone("America/Los_Angeles", &tz));
805   time_point<chrono::nanoseconds> tp;
806 
807   // We can parse a string without a UTC offset if we supply a timezone.
808   EXPECT_TRUE(parse("%Y-%m-%d %H:%M:%S", "2013-06-28 19:08:09", tz, &tp));
809   ExpectTime(tp, tz, 2013, 6, 28, 19, 8, 9, -7 * 60 * 60, true, "PDT");
810 
811   // But the timezone is ignored when a UTC offset is present.
812   EXPECT_TRUE(parse("%Y-%m-%d %H:%M:%S %z", "2013-06-28 19:08:09 +0800",
813                     utc_time_zone(), &tp));
814   ExpectTime(tp, tz, 2013, 6, 28, 19 - 8 - 7, 8, 9, -7 * 60 * 60, true, "PDT");
815 
816   // Check a skipped time (a Spring DST transition). parse() uses the
817   // pre-transition offset.
818   EXPECT_TRUE(parse("%Y-%m-%d %H:%M:%S", "2011-03-13 02:15:00", tz, &tp));
819   ExpectTime(tp, tz, 2011, 3, 13, 3, 15, 0, -7 * 60 * 60, true, "PDT");
820 
821   // Check a repeated time (a Fall DST transition).  parse() uses the
822   // pre-transition offset.
823   EXPECT_TRUE(parse("%Y-%m-%d %H:%M:%S", "2011-11-06 01:15:00", tz, &tp));
824   ExpectTime(tp, tz, 2011, 11, 6, 1, 15, 0, -7 * 60 * 60, true, "PDT");
825 }
826 
TEST(Parse,LeapSecond)827 TEST(Parse, LeapSecond) {
828   time_zone tz;
829   EXPECT_TRUE(load_time_zone("America/Los_Angeles", &tz));
830   time_point<chrono::nanoseconds> tp;
831 
832   // ":59" -> ":59"
833   EXPECT_TRUE(parse(RFC3339_full, "2013-06-28T07:08:59-08:00", tz, &tp));
834   ExpectTime(tp, tz, 2013, 6, 28, 8, 8, 59, -7 * 60 * 60, true, "PDT");
835 
836   // ":59.5" -> ":59.5"
837   EXPECT_TRUE(parse(RFC3339_full, "2013-06-28T07:08:59.5-08:00", tz, &tp));
838   ExpectTime(tp, tz, 2013, 6, 28, 8, 8, 59, -7 * 60 * 60, true, "PDT");
839 
840   // ":60" -> ":00"
841   EXPECT_TRUE(parse(RFC3339_full, "2013-06-28T07:08:60-08:00", tz, &tp));
842   ExpectTime(tp, tz, 2013, 6, 28, 8, 9, 0, -7 * 60 * 60, true, "PDT");
843 
844   // ":60.5" -> ":00.0"
845   EXPECT_TRUE(parse(RFC3339_full, "2013-06-28T07:08:60.5-08:00", tz, &tp));
846   ExpectTime(tp, tz, 2013, 6, 28, 8, 9, 0, -7 * 60 * 60, true, "PDT");
847 
848   // ":61" -> error
849   EXPECT_FALSE(parse(RFC3339_full, "2013-06-28T07:08:61-08:00", tz, &tp));
850 }
851 
TEST(Parse,ErrorCases)852 TEST(Parse, ErrorCases) {
853   const time_zone tz = utc_time_zone();
854   auto tp = chrono::system_clock::from_time_t(0);
855 
856   // Illegal trailing data.
857   EXPECT_FALSE(parse("%S", "123", tz, &tp));
858 
859   // Can't parse an illegal format specifier.
860   EXPECT_FALSE(parse("%Q", "x", tz, &tp));
861 
862   // Fails because of trailing, unparsed data "blah".
863   EXPECT_FALSE(parse("%m-%d", "2-3 blah", tz, &tp));
864 
865   // Trailing whitespace is allowed.
866   EXPECT_TRUE(parse("%m-%d", "2-3  ", tz, &tp));
867   EXPECT_EQ(2, convert(tp, utc_time_zone()).month());
868   EXPECT_EQ(3, convert(tp, utc_time_zone()).day());
869 
870   // Feb 31 requires normalization.
871   EXPECT_FALSE(parse("%m-%d", "2-31", tz, &tp));
872 
873   // Check that we cannot have spaces in UTC offsets.
874   EXPECT_TRUE(parse("%z", "-0203", tz, &tp));
875   EXPECT_FALSE(parse("%z", "- 2 3", tz, &tp));
876   EXPECT_TRUE(parse("%Ez", "-02:03", tz, &tp));
877   EXPECT_FALSE(parse("%Ez", "- 2: 3", tz, &tp));
878 
879   // Check that we reject other malformed UTC offsets.
880   EXPECT_FALSE(parse("%Ez", "+-08:00", tz, &tp));
881   EXPECT_FALSE(parse("%Ez", "-+08:00", tz, &tp));
882 
883   // Check that we do not accept "-0" in fields that allow zero.
884   EXPECT_FALSE(parse("%Y", "-0", tz, &tp));
885   EXPECT_FALSE(parse("%E4Y", "-0", tz, &tp));
886   EXPECT_FALSE(parse("%H", "-0", tz, &tp));
887   EXPECT_FALSE(parse("%M", "-0", tz, &tp));
888   EXPECT_FALSE(parse("%S", "-0", tz, &tp));
889   EXPECT_FALSE(parse("%z", "+-000", tz, &tp));
890   EXPECT_FALSE(parse("%Ez", "+-0:00", tz, &tp));
891   EXPECT_FALSE(parse("%z", "-00-0", tz, &tp));
892   EXPECT_FALSE(parse("%Ez", "-00:-0", tz, &tp));
893 }
894 
TEST(Parse,PosixConversions)895 TEST(Parse, PosixConversions) {
896   time_zone tz = utc_time_zone();
897   auto tp = chrono::system_clock::from_time_t(0);
898   const auto reset = convert(civil_second(1977, 6, 28, 9, 8, 7), tz);
899 
900   tp = reset;
901   EXPECT_TRUE(parse("%d", "15", tz, &tp));
902   EXPECT_EQ(15, convert(tp, tz).day());
903 
904   // %e is an extension, but is supported internally.
905   tp = reset;
906   EXPECT_TRUE(parse("%e", "15", tz, &tp));
907   EXPECT_EQ(15, convert(tp, tz).day());  // Equivalent to %d
908 
909   tp = reset;
910   EXPECT_TRUE(parse("%H", "17", tz, &tp));
911   EXPECT_EQ(17, convert(tp, tz).hour());
912 
913   tp = reset;
914   EXPECT_TRUE(parse("%I", "5", tz, &tp));
915   EXPECT_EQ(5, convert(tp, tz).hour());
916 
917   // %j is parsed but ignored.
918   EXPECT_TRUE(parse("%j", "32", tz, &tp));
919 
920   tp = reset;
921   EXPECT_TRUE(parse("%m", "11", tz, &tp));
922   EXPECT_EQ(11, convert(tp, tz).month());
923 
924   tp = reset;
925   EXPECT_TRUE(parse("%M", "33", tz, &tp));
926   EXPECT_EQ(33, convert(tp, tz).minute());
927 
928   tp = reset;
929   EXPECT_TRUE(parse("%S", "55", tz, &tp));
930   EXPECT_EQ(55, convert(tp, tz).second());
931 
932   // %U is parsed but ignored.
933   EXPECT_TRUE(parse("%U", "15", tz, &tp));
934 
935   // %w is parsed but ignored.
936   EXPECT_TRUE(parse("%w", "2", tz, &tp));
937 
938   // %W is parsed but ignored.
939   EXPECT_TRUE(parse("%W", "22", tz, &tp));
940 
941   tp = reset;
942   EXPECT_TRUE(parse("%y", "04", tz, &tp));
943   EXPECT_EQ(2004, convert(tp, tz).year());
944 
945   tp = reset;
946   EXPECT_TRUE(parse("%Y", "2004", tz, &tp));
947   EXPECT_EQ(2004, convert(tp, tz).year());
948 
949   EXPECT_TRUE(parse("%%", "%", tz, &tp));
950 
951 #if defined(__linux__)
952   // SU/C99/TZ extensions
953 
954   // Because we handle each (non-internal) specifier in a separate call
955   // to strptime(), there is no way to group %C and %y together.  So we
956   // just skip the %C/%y case.
957 #if 0
958   tp = reset;
959   EXPECT_TRUE(parse("%C %y", "20 04", tz, &tp));
960   EXPECT_EQ(2004, convert(tp, tz).year());
961 #endif
962 
963   tp = reset;
964   EXPECT_TRUE(parse("%D", "02/03/04", tz, &tp));
965   EXPECT_EQ(2, convert(tp, tz).month());
966   EXPECT_EQ(3, convert(tp, tz).day());
967   EXPECT_EQ(2004, convert(tp, tz).year());
968 
969   EXPECT_TRUE(parse("%n", "\n", tz, &tp));
970 
971   tp = reset;
972   EXPECT_TRUE(parse("%R", "03:44", tz, &tp));
973   EXPECT_EQ(3, convert(tp, tz).hour());
974   EXPECT_EQ(44, convert(tp, tz).minute());
975 
976   EXPECT_TRUE(parse("%t", "\t\v\f\n\r ", tz, &tp));
977 
978   tp = reset;
979   EXPECT_TRUE(parse("%T", "03:44:55", tz, &tp));
980   EXPECT_EQ(3, convert(tp, tz).hour());
981   EXPECT_EQ(44, convert(tp, tz).minute());
982   EXPECT_EQ(55, convert(tp, tz).second());
983 
984   tp = reset;
985   EXPECT_TRUE(parse("%s", "1234567890", tz, &tp));
986   EXPECT_EQ(chrono::system_clock::from_time_t(1234567890), tp);
987 
988   // %s conversion, like %z/%Ez, pays no heed to the optional zone.
989   time_zone lax;
990   EXPECT_TRUE(load_time_zone("America/Los_Angeles", &lax));
991   tp = reset;
992   EXPECT_TRUE(parse("%s", "1234567890", lax, &tp));
993   EXPECT_EQ(chrono::system_clock::from_time_t(1234567890), tp);
994 
995   // This is most important when the time has the same YMDhms
996   // breakdown in the zone as some other time.  For example, ...
997   //  1414917000 in US/Pacific -> Sun Nov 2 01:30:00 2014 (PDT)
998   //  1414920600 in US/Pacific -> Sun Nov 2 01:30:00 2014 (PST)
999   tp = reset;
1000   EXPECT_TRUE(parse("%s", "1414917000", lax, &tp));
1001   EXPECT_EQ(chrono::system_clock::from_time_t(1414917000), tp);
1002   tp = reset;
1003   EXPECT_TRUE(parse("%s", "1414920600", lax, &tp));
1004   EXPECT_EQ(chrono::system_clock::from_time_t(1414920600), tp);
1005 #endif
1006 }
1007 
TEST(Parse,LocaleSpecific)1008 TEST(Parse, LocaleSpecific) {
1009   time_zone tz = utc_time_zone();
1010   auto tp = chrono::system_clock::from_time_t(0);
1011   const auto reset = convert(civil_second(1977, 6, 28, 9, 8, 7), tz);
1012 
1013   // %a is parsed but ignored.
1014   EXPECT_TRUE(parse("%a", "Mon", tz, &tp));
1015 
1016   // %A is parsed but ignored.
1017   EXPECT_TRUE(parse("%A", "Monday", tz, &tp));
1018 
1019   tp = reset;
1020   EXPECT_TRUE(parse("%b", "Feb", tz, &tp));
1021   EXPECT_EQ(2, convert(tp, tz).month());
1022 
1023   tp = reset;
1024   EXPECT_TRUE(parse("%B", "February", tz, &tp));
1025   EXPECT_EQ(2, convert(tp, tz).month());
1026 
1027   // %p is parsed but ignored if it's alone.  But it's used with %I.
1028   EXPECT_TRUE(parse("%p", "AM", tz, &tp));
1029   tp = reset;
1030   EXPECT_TRUE(parse("%I %p", "5 PM", tz, &tp));
1031   EXPECT_EQ(17, convert(tp, tz).hour());
1032 
1033   tp = reset;
1034   EXPECT_TRUE(parse("%x", "02/03/04", tz, &tp));
1035   if (convert(tp, tz).month() == 2) {
1036     EXPECT_EQ(3, convert(tp, tz).day());
1037   } else {
1038     EXPECT_EQ(2, convert(tp, tz).day());
1039     EXPECT_EQ(3, convert(tp, tz).month());
1040   }
1041   EXPECT_EQ(2004, convert(tp, tz).year());
1042 
1043   tp = reset;
1044   EXPECT_TRUE(parse("%X", "15:44:55", tz, &tp));
1045   EXPECT_EQ(15, convert(tp, tz).hour());
1046   EXPECT_EQ(44, convert(tp, tz).minute());
1047   EXPECT_EQ(55, convert(tp, tz).second());
1048 
1049 #if defined(__linux__)
1050   // SU/C99/TZ extensions
1051 
1052   tp = reset;
1053   EXPECT_TRUE(parse("%h", "Feb", tz, &tp));
1054   EXPECT_EQ(2, convert(tp, tz).month());  // Equivalent to %b
1055 
1056 #if defined(__GLIBC__)
1057   tp = reset;
1058   EXPECT_TRUE(parse("%l %p", "5 PM", tz, &tp));
1059   EXPECT_EQ(17, convert(tp, tz).hour());
1060 #endif
1061 
1062   tp = reset;
1063   EXPECT_TRUE(parse("%r", "03:44:55 PM", tz, &tp));
1064   EXPECT_EQ(15, convert(tp, tz).hour());
1065   EXPECT_EQ(44, convert(tp, tz).minute());
1066   EXPECT_EQ(55, convert(tp, tz).second());
1067 
1068 #if defined(__GLIBC__)
1069   tp = reset;
1070   EXPECT_TRUE(parse("%Ec", "Tue Nov 19 05:06:07 2013", tz, &tp));
1071   EXPECT_EQ(convert(civil_second(2013, 11, 19, 5, 6, 7), tz), tp);
1072 
1073   // Modified conversion specifiers %E_
1074 
1075   tp = reset;
1076   EXPECT_TRUE(parse("%Ex", "02/03/04", tz, &tp));
1077   EXPECT_EQ(2, convert(tp, tz).month());
1078   EXPECT_EQ(3, convert(tp, tz).day());
1079   EXPECT_EQ(2004, convert(tp, tz).year());
1080 
1081   tp = reset;
1082   EXPECT_TRUE(parse("%EX", "15:44:55", tz, &tp));
1083   EXPECT_EQ(15, convert(tp, tz).hour());
1084   EXPECT_EQ(44, convert(tp, tz).minute());
1085   EXPECT_EQ(55, convert(tp, tz).second());
1086 
1087   // %Ey, the year offset from %EC, doesn't really make sense alone as there
1088   // is no way to represent it in tm_year (%EC is not simply the century).
1089   // Yet, because we handle each (non-internal) specifier in a separate call
1090   // to strptime(), there is no way to group %EC and %Ey either.  So we just
1091   // skip the %EC and %Ey cases.
1092 
1093   tp = reset;
1094   EXPECT_TRUE(parse("%EY", "2004", tz, &tp));
1095   EXPECT_EQ(2004, convert(tp, tz).year());
1096 
1097   // Modified conversion specifiers %O_
1098 
1099   tp = reset;
1100   EXPECT_TRUE(parse("%Od", "15", tz, &tp));
1101   EXPECT_EQ(15, convert(tp, tz).day());
1102 
1103   tp = reset;
1104   EXPECT_TRUE(parse("%Oe", "15", tz, &tp));
1105   EXPECT_EQ(15, convert(tp, tz).day());  // Equivalent to %d
1106 
1107   tp = reset;
1108   EXPECT_TRUE(parse("%OH", "17", tz, &tp));
1109   EXPECT_EQ(17, convert(tp, tz).hour());
1110 
1111   tp = reset;
1112   EXPECT_TRUE(parse("%OI", "5", tz, &tp));
1113   EXPECT_EQ(5, convert(tp, tz).hour());
1114 
1115   tp = reset;
1116   EXPECT_TRUE(parse("%Om", "11", tz, &tp));
1117   EXPECT_EQ(11, convert(tp, tz).month());
1118 
1119   tp = reset;
1120   EXPECT_TRUE(parse("%OM", "33", tz, &tp));
1121   EXPECT_EQ(33, convert(tp, tz).minute());
1122 
1123   tp = reset;
1124   EXPECT_TRUE(parse("%OS", "55", tz, &tp));
1125   EXPECT_EQ(55, convert(tp, tz).second());
1126 
1127   // %OU is parsed but ignored.
1128   EXPECT_TRUE(parse("%OU", "15", tz, &tp));
1129 
1130   // %Ow is parsed but ignored.
1131   EXPECT_TRUE(parse("%Ow", "2", tz, &tp));
1132 
1133   // %OW is parsed but ignored.
1134   EXPECT_TRUE(parse("%OW", "22", tz, &tp));
1135 
1136   tp = reset;
1137   EXPECT_TRUE(parse("%Oy", "04", tz, &tp));
1138   EXPECT_EQ(2004, convert(tp, tz).year());
1139 #endif
1140 #endif
1141 }
1142 
TEST(Parse,ExtendedSeconds)1143 TEST(Parse, ExtendedSeconds) {
1144   const time_zone tz = utc_time_zone();
1145   const time_point<chrono::nanoseconds> unix_epoch =
1146       chrono::system_clock::from_time_t(0);
1147 
1148   // All %E<prec>S cases are treated the same as %E*S on input.
1149   auto precisions = {"*", "0", "1",  "2",  "3",  "4",  "5",  "6", "7",
1150                      "8", "9", "10", "11", "12", "13", "14", "15"};
1151   for (const std::string prec : precisions) {
1152     const std::string fmt = "%E" + prec + "S";
1153     SCOPED_TRACE(fmt);
1154     time_point<chrono::nanoseconds> tp = unix_epoch;
1155     EXPECT_TRUE(parse(fmt, "5", tz, &tp));
1156     EXPECT_EQ(unix_epoch + chrono::seconds(5), tp);
1157     tp = unix_epoch;
1158     EXPECT_TRUE(parse(fmt, "05", tz, &tp));
1159     EXPECT_EQ(unix_epoch + chrono::seconds(5), tp);
1160     tp = unix_epoch;
1161     EXPECT_TRUE(parse(fmt, "05.0", tz, &tp));
1162     EXPECT_EQ(unix_epoch + chrono::seconds(5), tp);
1163     tp = unix_epoch;
1164     EXPECT_TRUE(parse(fmt, "05.00", tz, &tp));
1165     EXPECT_EQ(unix_epoch + chrono::seconds(5), tp);
1166     tp = unix_epoch;
1167     EXPECT_TRUE(parse(fmt, "05.6", tz, &tp));
1168     EXPECT_EQ(unix_epoch + chrono::seconds(5) + chrono::milliseconds(600), tp);
1169     tp = unix_epoch;
1170     EXPECT_TRUE(parse(fmt, "05.60", tz, &tp));
1171     EXPECT_EQ(unix_epoch + chrono::seconds(5) + chrono::milliseconds(600), tp);
1172     tp = unix_epoch;
1173     EXPECT_TRUE(parse(fmt, "05.600", tz, &tp));
1174     EXPECT_EQ(unix_epoch + chrono::seconds(5) + chrono::milliseconds(600), tp);
1175     tp = unix_epoch;
1176     EXPECT_TRUE(parse(fmt, "05.67", tz, &tp));
1177     EXPECT_EQ(unix_epoch + chrono::seconds(5) + chrono::milliseconds(670), tp);
1178     tp = unix_epoch;
1179     EXPECT_TRUE(parse(fmt, "05.670", tz, &tp));
1180     EXPECT_EQ(unix_epoch + chrono::seconds(5) + chrono::milliseconds(670), tp);
1181     tp = unix_epoch;
1182     EXPECT_TRUE(parse(fmt, "05.678", tz, &tp));
1183     EXPECT_EQ(unix_epoch + chrono::seconds(5) + chrono::milliseconds(678), tp);
1184   }
1185 
1186   // Here is a "%E*S" case we got wrong for a while.  The fractional
1187   // part of the first instant is less than 2^31 and was correctly
1188   // parsed, while the second (and any subsecond field >=2^31) failed.
1189   time_point<chrono::nanoseconds> tp = unix_epoch;
1190   EXPECT_TRUE(parse("%E*S", "0.2147483647", tz, &tp));
1191   EXPECT_EQ(unix_epoch + chrono::nanoseconds(214748364), tp);
1192   tp = unix_epoch;
1193   EXPECT_TRUE(parse("%E*S", "0.2147483648", tz, &tp));
1194   EXPECT_EQ(unix_epoch + chrono::nanoseconds(214748364), tp);
1195 
1196   // We should also be able to specify long strings of digits far
1197   // beyond the current resolution and have them convert the same way.
1198   tp = unix_epoch;
1199   EXPECT_TRUE(parse(
1200       "%E*S", "0.214748364801234567890123456789012345678901234567890123456789",
1201       tz, &tp));
1202   EXPECT_EQ(unix_epoch + chrono::nanoseconds(214748364), tp);
1203 }
1204 
TEST(Parse,ExtendedSecondsScan)1205 TEST(Parse, ExtendedSecondsScan) {
1206   const time_zone tz = utc_time_zone();
1207   time_point<chrono::nanoseconds> tp;
1208   for (int ms = 0; ms < 1000; ms += 111) {
1209     for (int us = 0; us < 1000; us += 27) {
1210       const int micros = ms * 1000 + us;
1211       for (int ns = 0; ns < 1000; ns += 9) {
1212         const auto expected = chrono::system_clock::from_time_t(0) +
1213                               chrono::nanoseconds(micros * 1000 + ns);
1214         std::ostringstream oss;
1215         oss << "0." << std::setfill('0') << std::setw(3);
1216         oss << ms << std::setw(3) << us << std::setw(3) << ns;
1217         const std::string input = oss.str();
1218         EXPECT_TRUE(parse("%E*S", input, tz, &tp));
1219         EXPECT_EQ(expected, tp) << input;
1220       }
1221     }
1222   }
1223 }
1224 
TEST(Parse,ExtendedSubeconds)1225 TEST(Parse, ExtendedSubeconds) {
1226   const time_zone tz = utc_time_zone();
1227   const time_point<chrono::nanoseconds> unix_epoch =
1228       chrono::system_clock::from_time_t(0);
1229 
1230   // All %E<prec>f cases are treated the same as %E*f on input.
1231   auto precisions = {"*", "0", "1",  "2",  "3",  "4",  "5",  "6", "7",
1232                      "8", "9", "10", "11", "12", "13", "14", "15"};
1233   for (const std::string prec : precisions) {
1234     const std::string fmt = "%E" + prec + "f";
1235     SCOPED_TRACE(fmt);
1236     time_point<chrono::nanoseconds> tp = unix_epoch - chrono::seconds(1);
1237     EXPECT_TRUE(parse(fmt, "", tz, &tp));
1238     EXPECT_EQ(unix_epoch, tp);
1239     tp = unix_epoch;
1240     EXPECT_TRUE(parse(fmt, "6", tz, &tp));
1241     EXPECT_EQ(unix_epoch + chrono::milliseconds(600), tp);
1242     tp = unix_epoch;
1243     EXPECT_TRUE(parse(fmt, "60", tz, &tp));
1244     EXPECT_EQ(unix_epoch + chrono::milliseconds(600), tp);
1245     tp = unix_epoch;
1246     EXPECT_TRUE(parse(fmt, "600", tz, &tp));
1247     EXPECT_EQ(unix_epoch + chrono::milliseconds(600), tp);
1248     tp = unix_epoch;
1249     EXPECT_TRUE(parse(fmt, "67", tz, &tp));
1250     EXPECT_EQ(unix_epoch + chrono::milliseconds(670), tp);
1251     tp = unix_epoch;
1252     EXPECT_TRUE(parse(fmt, "670", tz, &tp));
1253     EXPECT_EQ(unix_epoch + chrono::milliseconds(670), tp);
1254     tp = unix_epoch;
1255     EXPECT_TRUE(parse(fmt, "678", tz, &tp));
1256     EXPECT_EQ(unix_epoch + chrono::milliseconds(678), tp);
1257     tp = unix_epoch;
1258     EXPECT_TRUE(parse(fmt, "6789", tz, &tp));
1259     EXPECT_EQ(
1260         unix_epoch + chrono::milliseconds(678) + chrono::microseconds(900), tp);
1261   }
1262 
1263   // Here is a "%E*f" case we got wrong for a while.  The fractional
1264   // part of the first instant is less than 2^31 and was correctly
1265   // parsed, while the second (and any subsecond field >=2^31) failed.
1266   time_point<chrono::nanoseconds> tp = unix_epoch;
1267   EXPECT_TRUE(parse("%E*f", "2147483647", tz, &tp));
1268   EXPECT_EQ(unix_epoch + chrono::nanoseconds(214748364), tp);
1269   tp = unix_epoch;
1270   EXPECT_TRUE(parse("%E*f", "2147483648", tz, &tp));
1271   EXPECT_EQ(unix_epoch + chrono::nanoseconds(214748364), tp);
1272 
1273   // We should also be able to specify long strings of digits far
1274   // beyond the current resolution and have them convert the same way.
1275   tp = unix_epoch;
1276   EXPECT_TRUE(parse(
1277       "%E*f", "214748364801234567890123456789012345678901234567890123456789",
1278       tz, &tp));
1279   EXPECT_EQ(unix_epoch + chrono::nanoseconds(214748364), tp);
1280 }
1281 
TEST(Parse,ExtendedSubecondsScan)1282 TEST(Parse, ExtendedSubecondsScan) {
1283   time_point<chrono::nanoseconds> tp;
1284   const time_zone tz = utc_time_zone();
1285   for (int ms = 0; ms < 1000; ms += 111) {
1286     for (int us = 0; us < 1000; us += 27) {
1287       const int micros = ms * 1000 + us;
1288       for (int ns = 0; ns < 1000; ns += 9) {
1289         std::ostringstream oss;
1290         oss << std::setfill('0') << std::setw(3) << ms;
1291         oss << std::setw(3) << us << std::setw(3) << ns;
1292         const std::string nanos = oss.str();
1293         const auto expected = chrono::system_clock::from_time_t(0) +
1294                               chrono::nanoseconds(micros * 1000 + ns);
1295         for (int ps = 0; ps < 1000; ps += 250) {
1296           std::ostringstream ps_oss;
1297           oss << std::setfill('0') << std::setw(3) << ps;
1298           const std::string input = nanos + ps_oss.str() + "999";
1299           EXPECT_TRUE(parse("%E*f", input, tz, &tp));
1300           EXPECT_EQ(expected + chrono::nanoseconds(ps) / 1000, tp) << input;
1301         }
1302       }
1303     }
1304   }
1305 }
1306 
TEST(Parse,ExtendedOffset)1307 TEST(Parse, ExtendedOffset) {
1308   const time_zone utc = utc_time_zone();
1309   time_point<absl::time_internal::cctz::seconds> tp;
1310 
1311   EXPECT_TRUE(parse("%Ez", "+00:00", utc, &tp));
1312   EXPECT_EQ(convert(civil_second(1970, 1, 1, 0, 0, 0), utc), tp);
1313   EXPECT_TRUE(parse("%Ez", "-12:34", utc, &tp));
1314   EXPECT_EQ(convert(civil_second(1970, 1, 1, 12, 34, 0), utc), tp);
1315   EXPECT_TRUE(parse("%Ez", "+12:34", utc, &tp));
1316   EXPECT_EQ(convert(civil_second(1969, 12, 31, 11, 26, 0), utc), tp);
1317   EXPECT_FALSE(parse("%Ez", "-12:3", utc, &tp));
1318 
1319   for (auto fmt : {"%Ez", "%z"}) {
1320     EXPECT_TRUE(parse(fmt, "+0000", utc, &tp));
1321     EXPECT_EQ(convert(civil_second(1970, 1, 1, 0, 0, 0), utc), tp);
1322     EXPECT_TRUE(parse(fmt, "-1234", utc, &tp));
1323     EXPECT_EQ(convert(civil_second(1970, 1, 1, 12, 34, 0), utc), tp);
1324     EXPECT_TRUE(parse(fmt, "+1234", utc, &tp));
1325     EXPECT_EQ(convert(civil_second(1969, 12, 31, 11, 26, 0), utc), tp);
1326     EXPECT_FALSE(parse(fmt, "-123", utc, &tp));
1327 
1328     EXPECT_TRUE(parse(fmt, "+00", utc, &tp));
1329     EXPECT_EQ(convert(civil_second(1970, 1, 1, 0, 0, 0), utc), tp);
1330     EXPECT_TRUE(parse(fmt, "-12", utc, &tp));
1331     EXPECT_EQ(convert(civil_second(1970, 1, 1, 12, 0, 0), utc), tp);
1332     EXPECT_TRUE(parse(fmt, "+12", utc, &tp));
1333     EXPECT_EQ(convert(civil_second(1969, 12, 31, 12, 0, 0), utc), tp);
1334     EXPECT_FALSE(parse(fmt, "-1", utc, &tp));
1335   }
1336 }
1337 
TEST(Parse,ExtendedSecondOffset)1338 TEST(Parse, ExtendedSecondOffset) {
1339   const time_zone utc = utc_time_zone();
1340   time_point<absl::time_internal::cctz::seconds> tp;
1341 
1342   for (auto fmt : {"%Ez", "%E*z", "%:z", "%::z", "%:::z"}) {
1343     EXPECT_TRUE(parse(fmt, "+00:00:00", utc, &tp));
1344     EXPECT_EQ(convert(civil_second(1970, 1, 1, 0, 0, 0), utc), tp);
1345     EXPECT_TRUE(parse(fmt, "-12:34:56", utc, &tp));
1346     EXPECT_EQ(convert(civil_second(1970, 1, 1, 12, 34, 56), utc), tp);
1347     EXPECT_TRUE(parse(fmt, "+12:34:56", utc, &tp));
1348     EXPECT_EQ(convert(civil_second(1969, 12, 31, 11, 25, 4), utc), tp);
1349     EXPECT_FALSE(parse(fmt, "-12:34:5", utc, &tp));
1350 
1351     EXPECT_TRUE(parse(fmt, "+000000", utc, &tp));
1352     EXPECT_EQ(convert(civil_second(1970, 1, 1, 0, 0, 0), utc), tp);
1353     EXPECT_TRUE(parse(fmt, "-123456", utc, &tp));
1354     EXPECT_EQ(convert(civil_second(1970, 1, 1, 12, 34, 56), utc), tp);
1355     EXPECT_TRUE(parse(fmt, "+123456", utc, &tp));
1356     EXPECT_EQ(convert(civil_second(1969, 12, 31, 11, 25, 4), utc), tp);
1357     EXPECT_FALSE(parse(fmt, "-12345", utc, &tp));
1358 
1359     EXPECT_TRUE(parse(fmt, "+00:00", utc, &tp));
1360     EXPECT_EQ(convert(civil_second(1970, 1, 1, 0, 0, 0), utc), tp);
1361     EXPECT_TRUE(parse(fmt, "-12:34", utc, &tp));
1362     EXPECT_EQ(convert(civil_second(1970, 1, 1, 12, 34, 0), utc), tp);
1363     EXPECT_TRUE(parse(fmt, "+12:34", utc, &tp));
1364     EXPECT_EQ(convert(civil_second(1969, 12, 31, 11, 26, 0), utc), tp);
1365     EXPECT_FALSE(parse(fmt, "-12:3", utc, &tp));
1366 
1367     EXPECT_TRUE(parse(fmt, "+0000", utc, &tp));
1368     EXPECT_EQ(convert(civil_second(1970, 1, 1, 0, 0, 0), utc), tp);
1369     EXPECT_TRUE(parse(fmt, "-1234", utc, &tp));
1370     EXPECT_EQ(convert(civil_second(1970, 1, 1, 12, 34, 0), utc), tp);
1371     EXPECT_TRUE(parse(fmt, "+1234", utc, &tp));
1372     EXPECT_EQ(convert(civil_second(1969, 12, 31, 11, 26, 0), utc), tp);
1373     EXPECT_FALSE(parse(fmt, "-123", utc, &tp));
1374 
1375     EXPECT_TRUE(parse(fmt, "+00", utc, &tp));
1376     EXPECT_EQ(convert(civil_second(1970, 1, 1, 0, 0, 0), utc), tp);
1377     EXPECT_TRUE(parse(fmt, "-12", utc, &tp));
1378     EXPECT_EQ(convert(civil_second(1970, 1, 1, 12, 0, 0), utc), tp);
1379     EXPECT_TRUE(parse(fmt, "+12", utc, &tp));
1380     EXPECT_EQ(convert(civil_second(1969, 12, 31, 12, 0, 0), utc), tp);
1381     EXPECT_FALSE(parse(fmt, "-1", utc, &tp));
1382   }
1383 }
1384 
TEST(Parse,ExtendedYears)1385 TEST(Parse, ExtendedYears) {
1386   const time_zone utc = utc_time_zone();
1387   const char e4y_fmt[] = "%E4Y%m%d";  // no separators
1388   time_point<absl::time_internal::cctz::seconds> tp;
1389 
1390   // %E4Y consumes exactly four chars, including any sign.
1391   EXPECT_TRUE(parse(e4y_fmt, "-9991127", utc, &tp));
1392   EXPECT_EQ(convert(civil_second(-999, 11, 27, 0, 0, 0), utc), tp);
1393   EXPECT_TRUE(parse(e4y_fmt, "-0991127", utc, &tp));
1394   EXPECT_EQ(convert(civil_second(-99, 11, 27, 0, 0, 0), utc), tp);
1395   EXPECT_TRUE(parse(e4y_fmt, "-0091127", utc, &tp));
1396   EXPECT_EQ(convert(civil_second(-9, 11, 27, 0, 0, 0), utc), tp);
1397   EXPECT_TRUE(parse(e4y_fmt, "-0011127", utc, &tp));
1398   EXPECT_EQ(convert(civil_second(-1, 11, 27, 0, 0, 0), utc), tp);
1399   EXPECT_TRUE(parse(e4y_fmt, "00001127", utc, &tp));
1400   EXPECT_EQ(convert(civil_second(0, 11, 27, 0, 0, 0), utc), tp);
1401   EXPECT_TRUE(parse(e4y_fmt, "00011127", utc, &tp));
1402   EXPECT_EQ(convert(civil_second(1, 11, 27, 0, 0, 0), utc), tp);
1403   EXPECT_TRUE(parse(e4y_fmt, "00091127", utc, &tp));
1404   EXPECT_EQ(convert(civil_second(9, 11, 27, 0, 0, 0), utc), tp);
1405   EXPECT_TRUE(parse(e4y_fmt, "00991127", utc, &tp));
1406   EXPECT_EQ(convert(civil_second(99, 11, 27, 0, 0, 0), utc), tp);
1407   EXPECT_TRUE(parse(e4y_fmt, "09991127", utc, &tp));
1408   EXPECT_EQ(convert(civil_second(999, 11, 27, 0, 0, 0), utc), tp);
1409   EXPECT_TRUE(parse(e4y_fmt, "99991127", utc, &tp));
1410   EXPECT_EQ(convert(civil_second(9999, 11, 27, 0, 0, 0), utc), tp);
1411 
1412   // When the year is outside [-999:9999], the parse fails.
1413   EXPECT_FALSE(parse(e4y_fmt, "-10001127", utc, &tp));
1414   EXPECT_FALSE(parse(e4y_fmt, "100001127", utc, &tp));
1415 }
1416 
TEST(Parse,RFC3339Format)1417 TEST(Parse, RFC3339Format) {
1418   const time_zone tz = utc_time_zone();
1419   time_point<chrono::nanoseconds> tp;
1420   EXPECT_TRUE(parse(RFC3339_sec, "2014-02-12T20:21:00+00:00", tz, &tp));
1421   ExpectTime(tp, tz, 2014, 2, 12, 20, 21, 0, 0, false, "UTC");
1422 
1423   // Check that %ET also accepts "t".
1424   time_point<chrono::nanoseconds> tp2;
1425   EXPECT_TRUE(parse(RFC3339_sec, "2014-02-12t20:21:00+00:00", tz, &tp2));
1426   EXPECT_EQ(tp, tp2);
1427 
1428   // Check that %Ez also accepts "Z" as a synonym for "+00:00".
1429   time_point<chrono::nanoseconds> tp3;
1430   EXPECT_TRUE(parse(RFC3339_sec, "2014-02-12T20:21:00Z", tz, &tp3));
1431   EXPECT_EQ(tp, tp3);
1432 
1433   // Check that %Ez also accepts "z" as a synonym for "+00:00".
1434   time_point<chrono::nanoseconds> tp4;
1435   EXPECT_TRUE(parse(RFC3339_sec, "2014-02-12T20:21:00z", tz, &tp4));
1436   EXPECT_EQ(tp, tp4);
1437 }
1438 
TEST(Parse,Week)1439 TEST(Parse, Week) {
1440   const time_zone utc = utc_time_zone();
1441   time_point<absl::time_internal::cctz::seconds> tp;
1442 
1443   auto exp = convert(civil_second(2017, 1, 1, 0, 0, 0), utc);
1444   EXPECT_TRUE(parse("%Y-%U-%u", "2017-01-7", utc, &tp));
1445   EXPECT_EQ(exp, tp);
1446   EXPECT_TRUE(parse("%Y-%W-%w", "2017-00-0", utc, &tp));
1447   EXPECT_EQ(exp, tp);
1448 
1449   exp = convert(civil_second(2017, 12, 31, 0, 0, 0), utc);
1450   EXPECT_TRUE(parse("%Y-%U-%u", "2017-53-7", utc, &tp));
1451   EXPECT_EQ(exp, tp);
1452   EXPECT_TRUE(parse("%Y-%W-%w", "2017-52-0", utc, &tp));
1453   EXPECT_EQ(exp, tp);
1454 
1455   exp = convert(civil_second(2018, 1, 1, 0, 0, 0), utc);
1456   EXPECT_TRUE(parse("%Y-%U-%u", "2018-00-1", utc, &tp));
1457   EXPECT_EQ(exp, tp);
1458   EXPECT_TRUE(parse("%Y-%W-%w", "2018-01-1", utc, &tp));
1459   EXPECT_EQ(exp, tp);
1460 
1461   exp = convert(civil_second(2018, 12, 31, 0, 0, 0), utc);
1462   EXPECT_TRUE(parse("%Y-%U-%u", "2018-52-1", utc, &tp));
1463   EXPECT_EQ(exp, tp);
1464   EXPECT_TRUE(parse("%Y-%W-%w", "2018-53-1", utc, &tp));
1465   EXPECT_EQ(exp, tp);
1466 
1467   exp = convert(civil_second(2019, 1, 1, 0, 0, 0), utc);
1468   EXPECT_TRUE(parse("%Y-%U-%u", "2019-00-2", utc, &tp));
1469   EXPECT_EQ(exp, tp);
1470   EXPECT_TRUE(parse("%Y-%W-%w", "2019-00-2", utc, &tp));
1471   EXPECT_EQ(exp, tp);
1472 
1473   exp = convert(civil_second(2019, 12, 31, 0, 0, 0), utc);
1474   EXPECT_TRUE(parse("%Y-%U-%u", "2019-52-2", utc, &tp));
1475   EXPECT_EQ(exp, tp);
1476   EXPECT_TRUE(parse("%Y-%W-%w", "2019-52-2", utc, &tp));
1477   EXPECT_EQ(exp, tp);
1478 }
1479 
TEST(Parse,WeekYearShift)1480 TEST(Parse, WeekYearShift) {
1481   // %U/%W conversions with week values in {0, 52, 53} can slip
1482   // into the previous/following calendar years.
1483   const time_zone utc = utc_time_zone();
1484   time_point<absl::time_internal::cctz::seconds> tp;
1485 
1486   auto exp = convert(civil_second(2019, 12, 31, 0, 0, 0), utc);
1487   EXPECT_TRUE(parse("%Y-%U-%u", "2020-00-2", utc, &tp));
1488   EXPECT_EQ(exp, tp);
1489   EXPECT_TRUE(parse("%Y-%W-%w", "2020-00-2", utc, &tp));
1490   EXPECT_EQ(exp, tp);
1491 
1492   exp = convert(civil_second(2021, 1, 1, 0, 0, 0), utc);
1493   EXPECT_TRUE(parse("%Y-%U-%u", "2020-52-5", utc, &tp));
1494   EXPECT_EQ(exp, tp);
1495   EXPECT_TRUE(parse("%Y-%W-%w", "2020-52-5", utc, &tp));
1496   EXPECT_EQ(exp, tp);
1497 
1498   // Slipping into the previous/following calendar years should fail when
1499   // we're already at the extremes.
1500   EXPECT_FALSE(parse("%Y-%U-%u", "-9223372036854775808-0-7", utc, &tp));
1501   EXPECT_FALSE(parse("%Y-%U-%u", "9223372036854775807-53-7", utc, &tp));
1502 }
1503 
TEST(Parse,MaxRange)1504 TEST(Parse, MaxRange) {
1505   const time_zone utc = utc_time_zone();
1506   time_point<absl::time_internal::cctz::seconds> tp;
1507 
1508   // tests the upper limit using +00:00 offset
1509   EXPECT_TRUE(
1510       parse(RFC3339_sec, "292277026596-12-04T15:30:07+00:00", utc, &tp));
1511   EXPECT_EQ(tp, time_point<absl::time_internal::cctz::seconds>::max());
1512   EXPECT_FALSE(
1513       parse(RFC3339_sec, "292277026596-12-04T15:30:08+00:00", utc, &tp));
1514 
1515   // tests the upper limit using -01:00 offset
1516   EXPECT_TRUE(
1517       parse(RFC3339_sec, "292277026596-12-04T14:30:07-01:00", utc, &tp));
1518   EXPECT_EQ(tp, time_point<absl::time_internal::cctz::seconds>::max());
1519   EXPECT_FALSE(
1520       parse(RFC3339_sec, "292277026596-12-04T14:30:08-01:00", utc, &tp));
1521 
1522   // tests the lower limit using +00:00 offset
1523   EXPECT_TRUE(
1524       parse(RFC3339_sec, "-292277022657-01-27T08:29:52+00:00", utc, &tp));
1525   EXPECT_EQ(tp, time_point<absl::time_internal::cctz::seconds>::min());
1526   EXPECT_FALSE(
1527       parse(RFC3339_sec, "-292277022657-01-27T08:29:51+00:00", utc, &tp));
1528 
1529   // tests the lower limit using +01:00 offset
1530   EXPECT_TRUE(
1531       parse(RFC3339_sec, "-292277022657-01-27T09:29:52+01:00", utc, &tp));
1532   EXPECT_EQ(tp, time_point<absl::time_internal::cctz::seconds>::min());
1533   EXPECT_FALSE(
1534       parse(RFC3339_sec, "-292277022657-01-27T08:29:51+01:00", utc, &tp));
1535 
1536   // tests max/min civil-second overflow
1537   EXPECT_FALSE(
1538       parse(RFC3339_sec, "9223372036854775807-12-31T23:59:59-00:01", utc, &tp));
1539   EXPECT_FALSE(parse(RFC3339_sec, "-9223372036854775808-01-01T00:00:00+00:01",
1540                      utc, &tp));
1541 }
1542 
TEST(Parse,TimePointOverflow)1543 TEST(Parse, TimePointOverflow) {
1544   const time_zone utc = utc_time_zone();
1545 
1546   using D = chrono::duration<std::int64_t, std::nano>;
1547   time_point<D> tp;
1548 
1549   EXPECT_TRUE(
1550       parse(RFC3339_full, "2262-04-11T23:47:16.8547758079+00:00", utc, &tp));
1551   EXPECT_EQ(tp, time_point<D>::max());
1552   EXPECT_EQ("2262-04-11T23:47:16.854775807+00:00",
1553             format(RFC3339_full, tp, utc));
1554 #if 0
1555   // TODO(#199): Will fail until cctz::parse() properly detects overflow.
1556   EXPECT_FALSE(
1557       parse(RFC3339_full, "2262-04-11T23:47:16.8547758080+00:00", utc, &tp));
1558   EXPECT_TRUE(
1559       parse(RFC3339_full, "1677-09-21T00:12:43.1452241920+00:00", utc, &tp));
1560   EXPECT_EQ(tp, time_point<D>::min());
1561   EXPECT_EQ("1677-09-21T00:12:43.145224192+00:00",
1562             format(RFC3339_full, tp, utc));
1563   EXPECT_FALSE(
1564       parse(RFC3339_full, "1677-09-21T00:12:43.1452241919+00:00", utc, &tp));
1565 #endif
1566 
1567   using DS = chrono::duration<std::int8_t, chrono::seconds::period>;
1568   time_point<DS> stp;
1569 
1570   EXPECT_TRUE(parse(RFC3339_full, "1970-01-01T00:02:07.9+00:00", utc, &stp));
1571   EXPECT_EQ(stp, time_point<DS>::max());
1572   EXPECT_EQ("1970-01-01T00:02:07+00:00", format(RFC3339_full, stp, utc));
1573   EXPECT_FALSE(parse(RFC3339_full, "1970-01-01T00:02:08+00:00", utc, &stp));
1574 
1575   EXPECT_TRUE(parse(RFC3339_full, "1969-12-31T23:57:52+00:00", utc, &stp));
1576   EXPECT_EQ(stp, time_point<DS>::min());
1577   EXPECT_EQ("1969-12-31T23:57:52+00:00", format(RFC3339_full, stp, utc));
1578   EXPECT_FALSE(parse(RFC3339_full, "1969-12-31T23:57:51.9+00:00", utc, &stp));
1579 
1580   using DM = chrono::duration<std::int8_t, chrono::minutes::period>;
1581   time_point<DM> mtp;
1582 
1583   EXPECT_TRUE(parse(RFC3339_full, "1970-01-01T02:07:59+00:00", utc, &mtp));
1584   EXPECT_EQ(mtp, time_point<DM>::max());
1585   EXPECT_EQ("1970-01-01T02:07:00+00:00", format(RFC3339_full, mtp, utc));
1586   EXPECT_FALSE(parse(RFC3339_full, "1970-01-01T02:08:00+00:00", utc, &mtp));
1587 
1588   EXPECT_TRUE(parse(RFC3339_full, "1969-12-31T21:52:00+00:00", utc, &mtp));
1589   EXPECT_EQ(mtp, time_point<DM>::min());
1590   EXPECT_EQ("1969-12-31T21:52:00+00:00", format(RFC3339_full, mtp, utc));
1591   EXPECT_FALSE(parse(RFC3339_full, "1969-12-31T21:51:59+00:00", utc, &mtp));
1592 }
1593 
TEST(Parse,TimePointOverflowFloor)1594 TEST(Parse, TimePointOverflowFloor) {
1595   const time_zone utc = utc_time_zone();
1596 
1597   using D = chrono::duration<std::int64_t, std::micro>;
1598   time_point<D> tp;
1599 
1600   EXPECT_TRUE(
1601       parse(RFC3339_full, "294247-01-10T04:00:54.7758079+00:00", utc, &tp));
1602   EXPECT_EQ(tp, time_point<D>::max());
1603   EXPECT_EQ("294247-01-10T04:00:54.775807+00:00",
1604             format(RFC3339_full, tp, utc));
1605 #if 0
1606   // TODO(#199): Will fail until cctz::parse() properly detects overflow.
1607   EXPECT_FALSE(
1608       parse(RFC3339_full, "294247-01-10T04:00:54.7758080+00:00", utc, &tp));
1609   EXPECT_TRUE(
1610       parse(RFC3339_full, "-290308-12-21T19:59:05.2241920+00:00", utc, &tp));
1611   EXPECT_EQ(tp, time_point<D>::min());
1612   EXPECT_EQ("-290308-12-21T19:59:05.224192+00:00",
1613             format(RFC3339_full, tp, utc));
1614   EXPECT_FALSE(
1615       parse(RFC3339_full, "-290308-12-21T19:59:05.2241919+00:00", utc, &tp));
1616 #endif
1617 }
1618 
1619 //
1620 // Roundtrip test for format()/parse().
1621 //
1622 
TEST(FormatParse,RoundTrip)1623 TEST(FormatParse, RoundTrip) {
1624   time_zone lax;
1625   EXPECT_TRUE(load_time_zone("America/Los_Angeles", &lax));
1626   const auto in = convert(civil_second(1977, 6, 28, 9, 8, 7), lax);
1627   const auto subseconds = chrono::nanoseconds(654321);
1628 
1629   // RFC3339, which renders subseconds.
1630   {
1631     time_point<chrono::nanoseconds> out;
1632     const std::string s = format(RFC3339_full, in + subseconds, lax);
1633     EXPECT_TRUE(parse(RFC3339_full, s, lax, &out)) << s;
1634     EXPECT_EQ(in + subseconds, out);  // RFC3339_full includes %Ez
1635   }
1636 
1637   // RFC1123, which only does whole seconds.
1638   {
1639     time_point<chrono::nanoseconds> out;
1640     const std::string s = format(RFC1123_full, in, lax);
1641     EXPECT_TRUE(parse(RFC1123_full, s, lax, &out)) << s;
1642     EXPECT_EQ(in, out);  // RFC1123_full includes %z
1643   }
1644 
1645 #if defined(_WIN32) || defined(_WIN64)
1646   // Initial investigations indicate the %c does not roundtrip on Windows.
1647   // TODO: Figure out what is going on here (perhaps a locale problem).
1648 #elif defined(__EMSCRIPTEN__)
1649   // strftime() and strptime() use different defintions for "%c" under
1650   // emscripten (see https://github.com/kripken/emscripten/pull/7491),
1651   // causing its round-trip test to fail.
1652 #else
1653   // Even though we don't know what %c will produce, it should roundtrip,
1654   // but only in the 0-offset timezone.
1655   {
1656     time_point<chrono::nanoseconds> out;
1657     time_zone utc = utc_time_zone();
1658     const std::string s = format("%c", in, utc);
1659     EXPECT_TRUE(parse("%c", s, utc, &out)) << s;
1660     EXPECT_EQ(in, out);
1661   }
1662 #endif
1663 }
1664 
TEST(FormatParse,RoundTripDistantFuture)1665 TEST(FormatParse, RoundTripDistantFuture) {
1666   const time_zone utc = utc_time_zone();
1667   const time_point<absl::time_internal::cctz::seconds> in =
1668       time_point<absl::time_internal::cctz::seconds>::max();
1669   const std::string s = format(RFC3339_full, in, utc);
1670   time_point<absl::time_internal::cctz::seconds> out;
1671   EXPECT_TRUE(parse(RFC3339_full, s, utc, &out)) << s;
1672   EXPECT_EQ(in, out);
1673 }
1674 
TEST(FormatParse,RoundTripDistantPast)1675 TEST(FormatParse, RoundTripDistantPast) {
1676   const time_zone utc = utc_time_zone();
1677   const time_point<absl::time_internal::cctz::seconds> in =
1678       time_point<absl::time_internal::cctz::seconds>::min();
1679   const std::string s = format(RFC3339_full, in, utc);
1680   time_point<absl::time_internal::cctz::seconds> out;
1681   EXPECT_TRUE(parse(RFC3339_full, s, utc, &out)) << s;
1682   EXPECT_EQ(in, out);
1683 }
1684 
1685 }  // namespace cctz
1686 }  // namespace time_internal
1687 ABSL_NAMESPACE_END
1688 }  // namespace absl
1689