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


abseil_cpp
Author(s):
autogenerated on Wed Jun 19 2019 19:19:58