00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include <cstdint>
00016 #include <limits>
00017 #include <string>
00018
00019 #include "gmock/gmock.h"
00020 #include "gtest/gtest.h"
00021 #include "absl/time/internal/test_util.h"
00022 #include "absl/time/time.h"
00023
00024 using testing::HasSubstr;
00025
00026 namespace {
00027
00028
00029
00030 void TestFormatSpecifier(absl::Time t, absl::TimeZone tz,
00031 const std::string& fmt, const std::string& ans) {
00032 EXPECT_EQ(ans, absl::FormatTime(fmt, t, tz));
00033 EXPECT_EQ("xxx " + ans, absl::FormatTime("xxx " + fmt, t, tz));
00034 EXPECT_EQ(ans + " yyy", absl::FormatTime(fmt + " yyy", t, tz));
00035 EXPECT_EQ("xxx " + ans + " yyy",
00036 absl::FormatTime("xxx " + fmt + " yyy", t, tz));
00037 }
00038
00039
00040
00041
00042
00043 TEST(FormatTime, Basics) {
00044 absl::TimeZone tz = absl::UTCTimeZone();
00045 absl::Time t = absl::FromTimeT(0);
00046
00047
00048 EXPECT_EQ("", absl::FormatTime("", t, tz));
00049 EXPECT_EQ(" ", absl::FormatTime(" ", t, tz));
00050 EXPECT_EQ(" ", absl::FormatTime(" ", t, tz));
00051 EXPECT_EQ("xxx", absl::FormatTime("xxx", t, tz));
00052 std::string big(128, 'x');
00053 EXPECT_EQ(big, absl::FormatTime(big, t, tz));
00054
00055 std::string bigger(100000, 'x');
00056 EXPECT_EQ(bigger, absl::FormatTime(bigger, t, tz));
00057
00058 t += absl::Hours(13) + absl::Minutes(4) + absl::Seconds(5);
00059 t += absl::Milliseconds(6) + absl::Microseconds(7) + absl::Nanoseconds(8);
00060 EXPECT_EQ("1970-01-01", absl::FormatTime("%Y-%m-%d", t, tz));
00061 EXPECT_EQ("13:04:05", absl::FormatTime("%H:%M:%S", t, tz));
00062 EXPECT_EQ("13:04:05.006", absl::FormatTime("%H:%M:%E3S", t, tz));
00063 EXPECT_EQ("13:04:05.006007", absl::FormatTime("%H:%M:%E6S", t, tz));
00064 EXPECT_EQ("13:04:05.006007008", absl::FormatTime("%H:%M:%E9S", t, tz));
00065 }
00066
00067 TEST(FormatTime, LocaleSpecific) {
00068 const absl::TimeZone tz = absl::UTCTimeZone();
00069 absl::Time t = absl::FromTimeT(0);
00070
00071 TestFormatSpecifier(t, tz, "%a", "Thu");
00072 TestFormatSpecifier(t, tz, "%A", "Thursday");
00073 TestFormatSpecifier(t, tz, "%b", "Jan");
00074 TestFormatSpecifier(t, tz, "%B", "January");
00075
00076
00077 const std::string s =
00078 absl::FormatTime("%c", absl::FromTimeT(0), absl::UTCTimeZone());
00079 EXPECT_THAT(s, HasSubstr("1970"));
00080 EXPECT_THAT(s, HasSubstr("00:00:00"));
00081
00082 TestFormatSpecifier(t, tz, "%p", "AM");
00083 TestFormatSpecifier(t, tz, "%x", "01/01/70");
00084 TestFormatSpecifier(t, tz, "%X", "00:00:00");
00085 }
00086
00087 TEST(FormatTime, ExtendedSeconds) {
00088 const absl::TimeZone tz = absl::UTCTimeZone();
00089
00090
00091 absl::Time t = absl::FromTimeT(0) + absl::Seconds(5);
00092 EXPECT_EQ("05", absl::FormatTime("%E*S", t, tz));
00093 EXPECT_EQ("05.000000000000000", absl::FormatTime("%E15S", t, tz));
00094
00095
00096 t += absl::Milliseconds(6) + absl::Microseconds(7) + absl::Nanoseconds(8);
00097 EXPECT_EQ("05.006007008", absl::FormatTime("%E*S", t, tz));
00098 EXPECT_EQ("05", absl::FormatTime("%E0S", t, tz));
00099 EXPECT_EQ("05.006007008000000", absl::FormatTime("%E15S", t, tz));
00100
00101
00102 t = absl::FromUnixMicros(-1);
00103 EXPECT_EQ("1969-12-31 23:59:59.999999",
00104 absl::FormatTime("%Y-%m-%d %H:%M:%E*S", t, tz));
00105
00106
00107
00108
00109 t = absl::FromUnixMicros(1395024427333304);
00110 EXPECT_EQ("2014-03-17 02:47:07.333304",
00111 absl::FormatTime("%Y-%m-%d %H:%M:%E*S", t, tz));
00112 t += absl::Microseconds(1);
00113 EXPECT_EQ("2014-03-17 02:47:07.333305",
00114 absl::FormatTime("%Y-%m-%d %H:%M:%E*S", t, tz));
00115 }
00116
00117 TEST(FormatTime, RFC1123FormatPadsYear) {
00118 absl::TimeZone tz = absl::UTCTimeZone();
00119
00120
00121 absl::Time t = absl::FromCivil(absl::CivilSecond(77, 6, 28, 9, 8, 7), tz);
00122 EXPECT_EQ("Mon, 28 Jun 0077 09:08:07 +0000",
00123 absl::FormatTime(absl::RFC1123_full, t, tz));
00124 EXPECT_EQ("28 Jun 0077 09:08:07 +0000",
00125 absl::FormatTime(absl::RFC1123_no_wday, t, tz));
00126 }
00127
00128 TEST(FormatTime, InfiniteTime) {
00129 absl::TimeZone tz = absl::time_internal::LoadTimeZone("America/Los_Angeles");
00130
00131
00132 EXPECT_EQ("infinite-future",
00133 absl::FormatTime("%H:%M blah", absl::InfiniteFuture(), tz));
00134 EXPECT_EQ("infinite-past",
00135 absl::FormatTime("%H:%M blah", absl::InfinitePast(), tz));
00136 }
00137
00138
00139
00140
00141
00142 TEST(ParseTime, Basics) {
00143 absl::Time t = absl::FromTimeT(1234567890);
00144 std::string err;
00145
00146
00147 EXPECT_TRUE(absl::ParseTime("", "", &t, &err)) << err;
00148 EXPECT_EQ(absl::UnixEpoch(), t);
00149 EXPECT_TRUE(absl::ParseTime(" ", " ", &t, &err)) << err;
00150 EXPECT_TRUE(absl::ParseTime(" ", " ", &t, &err)) << err;
00151 EXPECT_TRUE(absl::ParseTime("x", "x", &t, &err)) << err;
00152 EXPECT_TRUE(absl::ParseTime("xxx", "xxx", &t, &err)) << err;
00153
00154 EXPECT_TRUE(absl::ParseTime("%Y-%m-%d %H:%M:%S %z",
00155 "2013-06-28 19:08:09 -0800", &t, &err))
00156 << err;
00157 const auto ci = absl::FixedTimeZone(-8 * 60 * 60).At(t);
00158 EXPECT_EQ(absl::CivilSecond(2013, 6, 28, 19, 8, 9), ci.cs);
00159 EXPECT_EQ(absl::ZeroDuration(), ci.subsecond);
00160 }
00161
00162 TEST(ParseTime, NullErrorString) {
00163 absl::Time t;
00164 EXPECT_FALSE(absl::ParseTime("%Q", "invalid format", &t, nullptr));
00165 EXPECT_FALSE(absl::ParseTime("%H", "12 trailing data", &t, nullptr));
00166 EXPECT_FALSE(
00167 absl::ParseTime("%H out of range", "42 out of range", &t, nullptr));
00168 }
00169
00170 TEST(ParseTime, WithTimeZone) {
00171 const absl::TimeZone tz =
00172 absl::time_internal::LoadTimeZone("America/Los_Angeles");
00173 absl::Time t;
00174 std::string e;
00175
00176
00177 EXPECT_TRUE(
00178 absl::ParseTime("%Y-%m-%d %H:%M:%S", "2013-06-28 19:08:09", tz, &t, &e))
00179 << e;
00180 auto ci = tz.At(t);
00181 EXPECT_EQ(absl::CivilSecond(2013, 6, 28, 19, 8, 9), ci.cs);
00182 EXPECT_EQ(absl::ZeroDuration(), ci.subsecond);
00183
00184
00185 EXPECT_TRUE(absl::ParseTime("%Y-%m-%d %H:%M:%S %z",
00186 "2013-06-28 19:08:09 +0800", tz, &t, &e))
00187 << e;
00188 ci = absl::FixedTimeZone(8 * 60 * 60).At(t);
00189 EXPECT_EQ(absl::CivilSecond(2013, 6, 28, 19, 8, 9), ci.cs);
00190 EXPECT_EQ(absl::ZeroDuration(), ci.subsecond);
00191 }
00192
00193 TEST(ParseTime, ErrorCases) {
00194 absl::Time t = absl::FromTimeT(0);
00195 std::string err;
00196
00197 EXPECT_FALSE(absl::ParseTime("%S", "123", &t, &err)) << err;
00198 EXPECT_THAT(err, HasSubstr("Illegal trailing data"));
00199
00200
00201 err.clear();
00202 EXPECT_FALSE(absl::ParseTime("%Q", "x", &t, &err)) << err;
00203
00204
00205 EXPECT_FALSE(err.empty());
00206
00207
00208 EXPECT_FALSE(absl::ParseTime("%m-%d", "2-3 blah", &t, &err)) << err;
00209 EXPECT_THAT(err, HasSubstr("Illegal trailing data"));
00210
00211
00212 EXPECT_FALSE(absl::ParseTime("%m-%d", "2-31", &t, &err)) << err;
00213 EXPECT_THAT(err, HasSubstr("Out-of-range"));
00214
00215
00216 EXPECT_TRUE(absl::ParseTime("%z", "-0203", &t, &err)) << err;
00217 EXPECT_FALSE(absl::ParseTime("%z", "- 2 3", &t, &err)) << err;
00218 EXPECT_THAT(err, HasSubstr("Failed to parse"));
00219 EXPECT_TRUE(absl::ParseTime("%Ez", "-02:03", &t, &err)) << err;
00220 EXPECT_FALSE(absl::ParseTime("%Ez", "- 2: 3", &t, &err)) << err;
00221 EXPECT_THAT(err, HasSubstr("Failed to parse"));
00222
00223
00224 EXPECT_FALSE(absl::ParseTime("%Ez", "+-08:00", &t, &err)) << err;
00225 EXPECT_THAT(err, HasSubstr("Failed to parse"));
00226 EXPECT_FALSE(absl::ParseTime("%Ez", "-+08:00", &t, &err)) << err;
00227 EXPECT_THAT(err, HasSubstr("Failed to parse"));
00228
00229
00230 EXPECT_FALSE(absl::ParseTime("%Y", "-0", &t, &err)) << err;
00231 EXPECT_THAT(err, HasSubstr("Failed to parse"));
00232 EXPECT_FALSE(absl::ParseTime("%E4Y", "-0", &t, &err)) << err;
00233 EXPECT_THAT(err, HasSubstr("Failed to parse"));
00234 EXPECT_FALSE(absl::ParseTime("%H", "-0", &t, &err)) << err;
00235 EXPECT_THAT(err, HasSubstr("Failed to parse"));
00236 EXPECT_FALSE(absl::ParseTime("%M", "-0", &t, &err)) << err;
00237 EXPECT_THAT(err, HasSubstr("Failed to parse"));
00238 EXPECT_FALSE(absl::ParseTime("%S", "-0", &t, &err)) << err;
00239 EXPECT_THAT(err, HasSubstr("Failed to parse"));
00240 EXPECT_FALSE(absl::ParseTime("%z", "+-000", &t, &err)) << err;
00241 EXPECT_THAT(err, HasSubstr("Failed to parse"));
00242 EXPECT_FALSE(absl::ParseTime("%Ez", "+-0:00", &t, &err)) << err;
00243 EXPECT_THAT(err, HasSubstr("Failed to parse"));
00244 EXPECT_FALSE(absl::ParseTime("%z", "-00-0", &t, &err)) << err;
00245 EXPECT_THAT(err, HasSubstr("Illegal trailing data"));
00246 EXPECT_FALSE(absl::ParseTime("%Ez", "-00:-0", &t, &err)) << err;
00247 EXPECT_THAT(err, HasSubstr("Illegal trailing data"));
00248 }
00249
00250 TEST(ParseTime, ExtendedSeconds) {
00251 std::string err;
00252 absl::Time t;
00253
00254
00255
00256
00257 t = absl::UnixEpoch();
00258 EXPECT_TRUE(absl::ParseTime("%E*S", "0.2147483647", &t, &err)) << err;
00259 EXPECT_EQ(absl::UnixEpoch() + absl::Nanoseconds(214748364) +
00260 absl::Nanoseconds(1) / 2,
00261 t);
00262 t = absl::UnixEpoch();
00263 EXPECT_TRUE(absl::ParseTime("%E*S", "0.2147483648", &t, &err)) << err;
00264 EXPECT_EQ(absl::UnixEpoch() + absl::Nanoseconds(214748364) +
00265 absl::Nanoseconds(3) / 4,
00266 t);
00267
00268
00269
00270 t = absl::UnixEpoch();
00271 EXPECT_TRUE(absl::ParseTime(
00272 "%E*S", "0.214748364801234567890123456789012345678901234567890123456789",
00273 &t, &err))
00274 << err;
00275 EXPECT_EQ(absl::UnixEpoch() + absl::Nanoseconds(214748364) +
00276 absl::Nanoseconds(3) / 4,
00277 t);
00278 }
00279
00280 TEST(ParseTime, ExtendedOffsetErrors) {
00281 std::string err;
00282 absl::Time t;
00283
00284
00285 EXPECT_FALSE(absl::ParseTime("%z", "-123", &t, &err)) << err;
00286 EXPECT_THAT(err, HasSubstr("Illegal trailing data"));
00287
00288
00289 EXPECT_FALSE(absl::ParseTime("%z", "-1", &t, &err)) << err;
00290 EXPECT_THAT(err, HasSubstr("Failed to parse"));
00291
00292
00293 EXPECT_FALSE(absl::ParseTime("%Ez", "-12:3", &t, &err)) << err;
00294 EXPECT_THAT(err, HasSubstr("Illegal trailing data"));
00295
00296
00297 EXPECT_FALSE(absl::ParseTime("%Ez", "-123", &t, &err)) << err;
00298 EXPECT_THAT(err, HasSubstr("Illegal trailing data"));
00299
00300
00301 EXPECT_FALSE(absl::ParseTime("%Ez", "-1", &t, &err)) << err;
00302 EXPECT_THAT(err, HasSubstr("Failed to parse"));
00303 }
00304
00305 TEST(ParseTime, InfiniteTime) {
00306 absl::Time t;
00307 std::string err;
00308 EXPECT_TRUE(absl::ParseTime("%H:%M blah", "infinite-future", &t, &err));
00309 EXPECT_EQ(absl::InfiniteFuture(), t);
00310
00311
00312 EXPECT_TRUE(absl::ParseTime("%H:%M blah", " infinite-future", &t, &err));
00313 EXPECT_EQ(absl::InfiniteFuture(), t);
00314 EXPECT_TRUE(absl::ParseTime("%H:%M blah", "infinite-future ", &t, &err));
00315 EXPECT_EQ(absl::InfiniteFuture(), t);
00316 EXPECT_TRUE(absl::ParseTime("%H:%M blah", " infinite-future ", &t, &err));
00317 EXPECT_EQ(absl::InfiniteFuture(), t);
00318
00319 EXPECT_TRUE(absl::ParseTime("%H:%M blah", "infinite-past", &t, &err));
00320 EXPECT_EQ(absl::InfinitePast(), t);
00321
00322
00323 EXPECT_TRUE(absl::ParseTime("%H:%M blah", " infinite-past", &t, &err));
00324 EXPECT_EQ(absl::InfinitePast(), t);
00325 EXPECT_TRUE(absl::ParseTime("%H:%M blah", "infinite-past ", &t, &err));
00326 EXPECT_EQ(absl::InfinitePast(), t);
00327 EXPECT_TRUE(absl::ParseTime("%H:%M blah", " infinite-past ", &t, &err));
00328 EXPECT_EQ(absl::InfinitePast(), t);
00329
00330
00331 absl::TimeZone tz = absl::UTCTimeZone();
00332 EXPECT_TRUE(absl::ParseTime("infinite-future %H:%M", "infinite-future 03:04",
00333 &t, &err));
00334 EXPECT_NE(absl::InfiniteFuture(), t);
00335 EXPECT_EQ(3, tz.At(t).cs.hour());
00336 EXPECT_EQ(4, tz.At(t).cs.minute());
00337
00338
00339 EXPECT_TRUE(
00340 absl::ParseTime("infinite-past %H:%M", "infinite-past 03:04", &t, &err));
00341 EXPECT_NE(absl::InfinitePast(), t);
00342 EXPECT_EQ(3, tz.At(t).cs.hour());
00343 EXPECT_EQ(4, tz.At(t).cs.minute());
00344
00345
00346 EXPECT_FALSE(absl::ParseTime("infinite-future %H:%M", "03:04", &t, &err));
00347 EXPECT_FALSE(absl::ParseTime("infinite-past %H:%M", "03:04", &t, &err));
00348 }
00349
00350 TEST(ParseTime, FailsOnUnrepresentableTime) {
00351 const absl::TimeZone utc = absl::UTCTimeZone();
00352 absl::Time t;
00353 EXPECT_FALSE(
00354 absl::ParseTime("%Y-%m-%d", "-292277022657-01-27", utc, &t, nullptr));
00355 EXPECT_TRUE(
00356 absl::ParseTime("%Y-%m-%d", "-292277022657-01-28", utc, &t, nullptr));
00357 EXPECT_TRUE(
00358 absl::ParseTime("%Y-%m-%d", "292277026596-12-04", utc, &t, nullptr));
00359 EXPECT_FALSE(
00360 absl::ParseTime("%Y-%m-%d", "292277026596-12-05", utc, &t, nullptr));
00361 }
00362
00363
00364
00365
00366
00367 TEST(FormatParse, RoundTrip) {
00368 const absl::TimeZone lax =
00369 absl::time_internal::LoadTimeZone("America/Los_Angeles");
00370 const absl::Time in =
00371 absl::FromCivil(absl::CivilSecond(1977, 6, 28, 9, 8, 7), lax);
00372 const absl::Duration subseconds = absl::Nanoseconds(654321);
00373 std::string err;
00374
00375
00376 {
00377 absl::Time out;
00378 const std::string s =
00379 absl::FormatTime(absl::RFC3339_full, in + subseconds, lax);
00380 EXPECT_TRUE(absl::ParseTime(absl::RFC3339_full, s, &out, &err))
00381 << s << ": " << err;
00382 EXPECT_EQ(in + subseconds, out);
00383 }
00384
00385
00386 {
00387 absl::Time out;
00388 const std::string s = absl::FormatTime(absl::RFC1123_full, in, lax);
00389 EXPECT_TRUE(absl::ParseTime(absl::RFC1123_full, s, &out, &err))
00390 << s << ": " << err;
00391 EXPECT_EQ(in, out);
00392 }
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403 #if !defined(_MSC_VER) && !defined(__EMSCRIPTEN__)
00404
00405
00406 {
00407 absl::Time out;
00408 const std::string s = absl::FormatTime("%c", in, absl::UTCTimeZone());
00409 EXPECT_TRUE(absl::ParseTime("%c", s, &out, &err)) << s << ": " << err;
00410 EXPECT_EQ(in, out);
00411 }
00412 #endif // !_MSC_VER && !__EMSCRIPTEN__
00413 }
00414
00415 TEST(FormatParse, RoundTripDistantFuture) {
00416 const absl::TimeZone tz = absl::UTCTimeZone();
00417 const absl::Time in =
00418 absl::FromUnixSeconds(std::numeric_limits<int64_t>::max());
00419 std::string err;
00420
00421 absl::Time out;
00422 const std::string s = absl::FormatTime(absl::RFC3339_full, in, tz);
00423 EXPECT_TRUE(absl::ParseTime(absl::RFC3339_full, s, &out, &err))
00424 << s << ": " << err;
00425 EXPECT_EQ(in, out);
00426 }
00427
00428 TEST(FormatParse, RoundTripDistantPast) {
00429 const absl::TimeZone tz = absl::UTCTimeZone();
00430 const absl::Time in =
00431 absl::FromUnixSeconds(std::numeric_limits<int64_t>::min());
00432 std::string err;
00433
00434 absl::Time out;
00435 const std::string s = absl::FormatTime(absl::RFC3339_full, in, tz);
00436 EXPECT_TRUE(absl::ParseTime(absl::RFC3339_full, s, &out, &err))
00437 << s << ": " << err;
00438 EXPECT_EQ(in, out);
00439 }
00440
00441 }