Abseil Common Libraries (C++) (grcp 依赖) https://abseil.io/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1244 lines
46 KiB

Export of internal Abseil changes -- f012012ef78234a6a4585321b67d7b7c92ebc266 by Laramie Leavitt <lar@google.com>: Slight restructuring of absl/random/internal randen implementation. Convert round-keys.inc into randen_round_keys.cc file. Consistently use a 128-bit pointer type for internal method parameters. This allows simpler pointer arithmetic in C++ & permits removal of some constants and casts. Remove some redundancy in comments & constexpr variables. Specifically, all references to Randen algorithm parameters use RandenTraits; duplication in RandenSlow removed. PiperOrigin-RevId: 312190313 -- dc8b42e054046741e9ed65335bfdface997c6063 by Abseil Team <absl-team@google.com>: Internal change. PiperOrigin-RevId: 312167304 -- f13d248fafaf206492c1362c3574031aea3abaf7 by Matthew Brown <matthewbr@google.com>: Cleanup StrFormat extensions a little. PiperOrigin-RevId: 312166336 -- 9d9117589667afe2332bb7ad42bc967ca7c54502 by Derek Mauro <dmauro@google.com>: Internal change PiperOrigin-RevId: 312105213 -- 9a12b9b3aa0e59b8ee6cf9408ed0029045543a9b by Abseil Team <absl-team@google.com>: Complete IGNORE_TYPE macro renaming. PiperOrigin-RevId: 311999699 -- 64756f20d61021d999bd0d4c15e9ad3857382f57 by Gennadiy Rozental <rogeeff@google.com>: Switch to fixed bytes specific default value. This fixes the Abseil Flags for big endian platforms. PiperOrigin-RevId: 311844448 -- bdbe6b5b29791dbc3816ada1828458b3010ff1e9 by Laramie Leavitt <lar@google.com>: Change many distribution tests to use pcg_engine as a deterministic source of entropy. It's reasonable to test that the BitGen itself has good entropy, however when testing the cross product of all random distributions x all the architecture variations x all submitted changes results in a large number of tests. In order to account for these failures while still using good entropy requires that our allowed sigma need to account for all of these independent tests. Our current sigma values are too restrictive, and we see a lot of failures, so we have to either relax the sigma values or convert some of the statistical tests to use deterministic values. This changelist does the latter. PiperOrigin-RevId: 311840096 GitOrigin-RevId: f012012ef78234a6a4585321b67d7b7c92ebc266 Change-Id: Ic84886f38ff30d7d72c126e9b63c9a61eb729a1a
5 years ago
// Copyright 2018 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "absl/time/civil_time.h"
#include <limits>
#include <sstream>
#include <type_traits>
#include "absl/base/macros.h"
#include "gtest/gtest.h"
namespace {
TEST(CivilTime, DefaultConstruction) {
absl::CivilSecond ss;
EXPECT_EQ("1970-01-01T00:00:00", absl::FormatCivilTime(ss));
absl::CivilMinute mm;
EXPECT_EQ("1970-01-01T00:00", absl::FormatCivilTime(mm));
absl::CivilHour hh;
EXPECT_EQ("1970-01-01T00", absl::FormatCivilTime(hh));
absl::CivilDay d;
EXPECT_EQ("1970-01-01", absl::FormatCivilTime(d));
absl::CivilMonth m;
EXPECT_EQ("1970-01", absl::FormatCivilTime(m));
absl::CivilYear y;
EXPECT_EQ("1970", absl::FormatCivilTime(y));
}
TEST(CivilTime, StructMember) {
struct S {
absl::CivilDay day;
};
S s = {};
EXPECT_EQ(absl::CivilDay{}, s.day);
}
TEST(CivilTime, FieldsConstruction) {
EXPECT_EQ("2015-01-02T03:04:05",
absl::FormatCivilTime(absl::CivilSecond(2015, 1, 2, 3, 4, 5)));
EXPECT_EQ("2015-01-02T03:04:00",
absl::FormatCivilTime(absl::CivilSecond(2015, 1, 2, 3, 4)));
EXPECT_EQ("2015-01-02T03:00:00",
absl::FormatCivilTime(absl::CivilSecond(2015, 1, 2, 3)));
EXPECT_EQ("2015-01-02T00:00:00",
absl::FormatCivilTime(absl::CivilSecond(2015, 1, 2)));
EXPECT_EQ("2015-01-01T00:00:00",
absl::FormatCivilTime(absl::CivilSecond(2015, 1)));
EXPECT_EQ("2015-01-01T00:00:00",
absl::FormatCivilTime(absl::CivilSecond(2015)));
EXPECT_EQ("2015-01-02T03:04",
absl::FormatCivilTime(absl::CivilMinute(2015, 1, 2, 3, 4, 5)));
EXPECT_EQ("2015-01-02T03:04",
absl::FormatCivilTime(absl::CivilMinute(2015, 1, 2, 3, 4)));
EXPECT_EQ("2015-01-02T03:00",
absl::FormatCivilTime(absl::CivilMinute(2015, 1, 2, 3)));
EXPECT_EQ("2015-01-02T00:00",
absl::FormatCivilTime(absl::CivilMinute(2015, 1, 2)));
EXPECT_EQ("2015-01-01T00:00",
absl::FormatCivilTime(absl::CivilMinute(2015, 1)));
EXPECT_EQ("2015-01-01T00:00",
absl::FormatCivilTime(absl::CivilMinute(2015)));
EXPECT_EQ("2015-01-02T03",
absl::FormatCivilTime(absl::CivilHour(2015, 1, 2, 3, 4, 5)));
EXPECT_EQ("2015-01-02T03",
absl::FormatCivilTime(absl::CivilHour(2015, 1, 2, 3, 4)));
EXPECT_EQ("2015-01-02T03",
absl::FormatCivilTime(absl::CivilHour(2015, 1, 2, 3)));
EXPECT_EQ("2015-01-02T00",
absl::FormatCivilTime(absl::CivilHour(2015, 1, 2)));
EXPECT_EQ("2015-01-01T00",
absl::FormatCivilTime(absl::CivilHour(2015, 1)));
EXPECT_EQ("2015-01-01T00",
absl::FormatCivilTime(absl::CivilHour(2015)));
EXPECT_EQ("2015-01-02",
absl::FormatCivilTime(absl::CivilDay(2015, 1, 2, 3, 4, 5)));
EXPECT_EQ("2015-01-02",
absl::FormatCivilTime(absl::CivilDay(2015, 1, 2, 3, 4)));
EXPECT_EQ("2015-01-02",
absl::FormatCivilTime(absl::CivilDay(2015, 1, 2, 3)));
EXPECT_EQ("2015-01-02",
absl::FormatCivilTime(absl::CivilDay(2015, 1, 2)));
EXPECT_EQ("2015-01-01",
absl::FormatCivilTime(absl::CivilDay(2015, 1)));
EXPECT_EQ("2015-01-01",
absl::FormatCivilTime(absl::CivilDay(2015)));
EXPECT_EQ("2015-01",
absl::FormatCivilTime(absl::CivilMonth(2015, 1, 2, 3, 4, 5)));
EXPECT_EQ("2015-01",
absl::FormatCivilTime(absl::CivilMonth(2015, 1, 2, 3, 4)));
EXPECT_EQ("2015-01",
absl::FormatCivilTime(absl::CivilMonth(2015, 1, 2, 3)));
EXPECT_EQ("2015-01",
absl::FormatCivilTime(absl::CivilMonth(2015, 1, 2)));
EXPECT_EQ("2015-01",
absl::FormatCivilTime(absl::CivilMonth(2015, 1)));
EXPECT_EQ("2015-01",
absl::FormatCivilTime(absl::CivilMonth(2015)));
EXPECT_EQ("2015",
absl::FormatCivilTime(absl::CivilYear(2015, 1, 2, 3, 4, 5)));
EXPECT_EQ("2015",
absl::FormatCivilTime(absl::CivilYear(2015, 1, 2, 3, 4)));
EXPECT_EQ("2015",
absl::FormatCivilTime(absl::CivilYear(2015, 1, 2, 3)));
EXPECT_EQ("2015",
absl::FormatCivilTime(absl::CivilYear(2015, 1, 2)));
EXPECT_EQ("2015",
absl::FormatCivilTime(absl::CivilYear(2015, 1)));
EXPECT_EQ("2015",
absl::FormatCivilTime(absl::CivilYear(2015)));
}
TEST(CivilTime, FieldsConstructionLimits) {
const int kIntMax = std::numeric_limits<int>::max();
EXPECT_EQ("2038-01-19T03:14:07",
absl::FormatCivilTime(absl::CivilSecond(
1970, 1, 1, 0, 0, kIntMax)));
EXPECT_EQ("6121-02-11T05:21:07",
absl::FormatCivilTime(absl::CivilSecond(
1970, 1, 1, 0, kIntMax, kIntMax)));
EXPECT_EQ("251104-11-20T12:21:07",
absl::FormatCivilTime(absl::CivilSecond(
1970, 1, 1, kIntMax, kIntMax, kIntMax)));
EXPECT_EQ("6130715-05-30T12:21:07",
absl::FormatCivilTime(absl::CivilSecond(
1970, 1, kIntMax, kIntMax, kIntMax, kIntMax)));
EXPECT_EQ("185087685-11-26T12:21:07",
absl::FormatCivilTime(absl::CivilSecond(
1970, kIntMax, kIntMax, kIntMax, kIntMax, kIntMax)));
const int kIntMin = std::numeric_limits<int>::min();
EXPECT_EQ("1901-12-13T20:45:52",
absl::FormatCivilTime(absl::CivilSecond(
1970, 1, 1, 0, 0, kIntMin)));
EXPECT_EQ("-2182-11-20T18:37:52",
absl::FormatCivilTime(absl::CivilSecond(
1970, 1, 1, 0, kIntMin, kIntMin)));
EXPECT_EQ("-247165-02-11T10:37:52",
absl::FormatCivilTime(absl::CivilSecond(
1970, 1, 1, kIntMin, kIntMin, kIntMin)));
EXPECT_EQ("-6126776-08-01T10:37:52",
absl::FormatCivilTime(absl::CivilSecond(
1970, 1, kIntMin, kIntMin, kIntMin, kIntMin)));
EXPECT_EQ("-185083747-10-31T10:37:52",
absl::FormatCivilTime(absl::CivilSecond(
1970, kIntMin, kIntMin, kIntMin, kIntMin, kIntMin)));
}
TEST(CivilTime, RangeLimits) {
const absl::civil_year_t kYearMax =
std::numeric_limits<absl::civil_year_t>::max();
EXPECT_EQ(absl::CivilYear(kYearMax),
absl::CivilYear::max());
EXPECT_EQ(absl::CivilMonth(kYearMax, 12),
absl::CivilMonth::max());
EXPECT_EQ(absl::CivilDay(kYearMax, 12, 31),
absl::CivilDay::max());
EXPECT_EQ(absl::CivilHour(kYearMax, 12, 31, 23),
absl::CivilHour::max());
EXPECT_EQ(absl::CivilMinute(kYearMax, 12, 31, 23, 59),
absl::CivilMinute::max());
EXPECT_EQ(absl::CivilSecond(kYearMax, 12, 31, 23, 59, 59),
absl::CivilSecond::max());
const absl::civil_year_t kYearMin =
std::numeric_limits<absl::civil_year_t>::min();
EXPECT_EQ(absl::CivilYear(kYearMin),
absl::CivilYear::min());
EXPECT_EQ(absl::CivilMonth(kYearMin, 1),
absl::CivilMonth::min());
EXPECT_EQ(absl::CivilDay(kYearMin, 1, 1),
absl::CivilDay::min());
EXPECT_EQ(absl::CivilHour(kYearMin, 1, 1, 0),
absl::CivilHour::min());
EXPECT_EQ(absl::CivilMinute(kYearMin, 1, 1, 0, 0),
absl::CivilMinute::min());
EXPECT_EQ(absl::CivilSecond(kYearMin, 1, 1, 0, 0, 0),
absl::CivilSecond::min());
}
TEST(CivilTime, ImplicitCrossAlignment) {
absl::CivilYear year(2015);
absl::CivilMonth month = year;
absl::CivilDay day = month;
absl::CivilHour hour = day;
absl::CivilMinute minute = hour;
absl::CivilSecond second = minute;
second = year;
EXPECT_EQ(second, year);
second = month;
EXPECT_EQ(second, month);
second = day;
EXPECT_EQ(second, day);
second = hour;
EXPECT_EQ(second, hour);
second = minute;
EXPECT_EQ(second, minute);
minute = year;
EXPECT_EQ(minute, year);
minute = month;
EXPECT_EQ(minute, month);
minute = day;
EXPECT_EQ(minute, day);
minute = hour;
EXPECT_EQ(minute, hour);
hour = year;
EXPECT_EQ(hour, year);
hour = month;
EXPECT_EQ(hour, month);
hour = day;
EXPECT_EQ(hour, day);
day = year;
EXPECT_EQ(day, year);
day = month;
EXPECT_EQ(day, month);
month = year;
EXPECT_EQ(month, year);
// Ensures unsafe conversions are not allowed.
EXPECT_FALSE(
(std::is_convertible<absl::CivilSecond, absl::CivilMinute>::value));
EXPECT_FALSE(
(std::is_convertible<absl::CivilSecond, absl::CivilHour>::value));
EXPECT_FALSE(
(std::is_convertible<absl::CivilSecond, absl::CivilDay>::value));
EXPECT_FALSE(
(std::is_convertible<absl::CivilSecond, absl::CivilMonth>::value));
EXPECT_FALSE(
(std::is_convertible<absl::CivilSecond, absl::CivilYear>::value));
EXPECT_FALSE(
(std::is_convertible<absl::CivilMinute, absl::CivilHour>::value));
EXPECT_FALSE(
(std::is_convertible<absl::CivilMinute, absl::CivilDay>::value));
EXPECT_FALSE(
(std::is_convertible<absl::CivilMinute, absl::CivilMonth>::value));
EXPECT_FALSE(
(std::is_convertible<absl::CivilMinute, absl::CivilYear>::value));
EXPECT_FALSE(
(std::is_convertible<absl::CivilHour, absl::CivilDay>::value));
EXPECT_FALSE(
(std::is_convertible<absl::CivilHour, absl::CivilMonth>::value));
EXPECT_FALSE(
(std::is_convertible<absl::CivilHour, absl::CivilYear>::value));
EXPECT_FALSE(
(std::is_convertible<absl::CivilDay, absl::CivilMonth>::value));
EXPECT_FALSE(
(std::is_convertible<absl::CivilDay, absl::CivilYear>::value));
EXPECT_FALSE(
(std::is_convertible<absl::CivilMonth, absl::CivilYear>::value));
}
TEST(CivilTime, ExplicitCrossAlignment) {
//
// Assign from smaller units -> larger units
//
absl::CivilSecond second(2015, 1, 2, 3, 4, 5);
EXPECT_EQ("2015-01-02T03:04:05", absl::FormatCivilTime(second));
absl::CivilMinute minute(second);
EXPECT_EQ("2015-01-02T03:04", absl::FormatCivilTime(minute));
absl::CivilHour hour(minute);
EXPECT_EQ("2015-01-02T03", absl::FormatCivilTime(hour));
absl::CivilDay day(hour);
EXPECT_EQ("2015-01-02", absl::FormatCivilTime(day));
absl::CivilMonth month(day);
EXPECT_EQ("2015-01", absl::FormatCivilTime(month));
absl::CivilYear year(month);
EXPECT_EQ("2015", absl::FormatCivilTime(year));
//
// Now assign from larger units -> smaller units
//
month = absl::CivilMonth(year);
EXPECT_EQ("2015-01", absl::FormatCivilTime(month));
day = absl::CivilDay(month);
EXPECT_EQ("2015-01-01", absl::FormatCivilTime(day));
hour = absl::CivilHour(day);
EXPECT_EQ("2015-01-01T00", absl::FormatCivilTime(hour));
minute = absl::CivilMinute(hour);
EXPECT_EQ("2015-01-01T00:00", absl::FormatCivilTime(minute));
second = absl::CivilSecond(minute);
EXPECT_EQ("2015-01-01T00:00:00", absl::FormatCivilTime(second));
}
// Metafunction to test whether difference is allowed between two types.
template <typename T1, typename T2>
struct HasDiff {
template <typename U1, typename U2>
static std::false_type test(...);
template <typename U1, typename U2>
static std::true_type test(decltype(std::declval<U1>() - std::declval<U2>()));
static constexpr bool value = decltype(test<T1, T2>(0))::value;
};
TEST(CivilTime, DisallowCrossAlignedDifference) {
// Difference is allowed between types with the same alignment.
static_assert(HasDiff<absl::CivilSecond, absl::CivilSecond>::value, "");
static_assert(HasDiff<absl::CivilMinute, absl::CivilMinute>::value, "");
static_assert(HasDiff<absl::CivilHour, absl::CivilHour>::value, "");
static_assert(HasDiff<absl::CivilDay, absl::CivilDay>::value, "");
static_assert(HasDiff<absl::CivilMonth, absl::CivilMonth>::value, "");
static_assert(HasDiff<absl::CivilYear, absl::CivilYear>::value, "");
// Difference is disallowed between types with different alignments.
static_assert(!HasDiff<absl::CivilSecond, absl::CivilMinute>::value, "");
static_assert(!HasDiff<absl::CivilSecond, absl::CivilHour>::value, "");
static_assert(!HasDiff<absl::CivilSecond, absl::CivilDay>::value, "");
static_assert(!HasDiff<absl::CivilSecond, absl::CivilMonth>::value, "");
static_assert(!HasDiff<absl::CivilSecond, absl::CivilYear>::value, "");
static_assert(!HasDiff<absl::CivilMinute, absl::CivilHour>::value, "");
static_assert(!HasDiff<absl::CivilMinute, absl::CivilDay>::value, "");
static_assert(!HasDiff<absl::CivilMinute, absl::CivilMonth>::value, "");
static_assert(!HasDiff<absl::CivilMinute, absl::CivilYear>::value, "");
static_assert(!HasDiff<absl::CivilHour, absl::CivilDay>::value, "");
static_assert(!HasDiff<absl::CivilHour, absl::CivilMonth>::value, "");
static_assert(!HasDiff<absl::CivilHour, absl::CivilYear>::value, "");
static_assert(!HasDiff<absl::CivilDay, absl::CivilMonth>::value, "");
static_assert(!HasDiff<absl::CivilDay, absl::CivilYear>::value, "");
static_assert(!HasDiff<absl::CivilMonth, absl::CivilYear>::value, "");
}
TEST(CivilTime, ValueSemantics) {
const absl::CivilHour a(2015, 1, 2, 3);
const absl::CivilHour b = a;
const absl::CivilHour c(b);
absl::CivilHour d;
d = c;
EXPECT_EQ("2015-01-02T03", absl::FormatCivilTime(d));
}
TEST(CivilTime, Relational) {
// Tests that the alignment unit is ignored in comparison.
const absl::CivilYear year(2014);
const absl::CivilMonth month(year);
EXPECT_EQ(year, month);
#define TEST_RELATIONAL(OLDER, YOUNGER) \
do { \
EXPECT_FALSE(OLDER < OLDER); \
EXPECT_FALSE(OLDER > OLDER); \
EXPECT_TRUE(OLDER >= OLDER); \
EXPECT_TRUE(OLDER <= OLDER); \
EXPECT_FALSE(YOUNGER < YOUNGER); \
EXPECT_FALSE(YOUNGER > YOUNGER); \
EXPECT_TRUE(YOUNGER >= YOUNGER); \
EXPECT_TRUE(YOUNGER <= YOUNGER); \
EXPECT_EQ(OLDER, OLDER); \
EXPECT_NE(OLDER, YOUNGER); \
EXPECT_LT(OLDER, YOUNGER); \
EXPECT_LE(OLDER, YOUNGER); \
EXPECT_GT(YOUNGER, OLDER); \
EXPECT_GE(YOUNGER, OLDER); \
} while (0)
// Alignment is ignored in comparison (verified above), so CivilSecond is
// used to test comparison in all field positions.
TEST_RELATIONAL(absl::CivilSecond(2014, 1, 1, 0, 0, 0),
absl::CivilSecond(2015, 1, 1, 0, 0, 0));
TEST_RELATIONAL(absl::CivilSecond(2014, 1, 1, 0, 0, 0),
absl::CivilSecond(2014, 2, 1, 0, 0, 0));
TEST_RELATIONAL(absl::CivilSecond(2014, 1, 1, 0, 0, 0),
absl::CivilSecond(2014, 1, 2, 0, 0, 0));
TEST_RELATIONAL(absl::CivilSecond(2014, 1, 1, 0, 0, 0),
absl::CivilSecond(2014, 1, 1, 1, 0, 0));
TEST_RELATIONAL(absl::CivilSecond(2014, 1, 1, 1, 0, 0),
absl::CivilSecond(2014, 1, 1, 1, 1, 0));
TEST_RELATIONAL(absl::CivilSecond(2014, 1, 1, 1, 1, 0),
absl::CivilSecond(2014, 1, 1, 1, 1, 1));
// Tests the relational operators of two different civil-time types.
TEST_RELATIONAL(absl::CivilDay(2014, 1, 1),
absl::CivilMinute(2014, 1, 1, 1, 1));
TEST_RELATIONAL(absl::CivilDay(2014, 1, 1),
absl::CivilMonth(2014, 2));
#undef TEST_RELATIONAL
}
TEST(CivilTime, Arithmetic) {
absl::CivilSecond second(2015, 1, 2, 3, 4, 5);
EXPECT_EQ("2015-01-02T03:04:06", absl::FormatCivilTime(second += 1));
EXPECT_EQ("2015-01-02T03:04:07", absl::FormatCivilTime(second + 1));
EXPECT_EQ("2015-01-02T03:04:08", absl::FormatCivilTime(2 + second));
EXPECT_EQ("2015-01-02T03:04:05", absl::FormatCivilTime(second - 1));
EXPECT_EQ("2015-01-02T03:04:05", absl::FormatCivilTime(second -= 1));
EXPECT_EQ("2015-01-02T03:04:05", absl::FormatCivilTime(second++));
EXPECT_EQ("2015-01-02T03:04:07", absl::FormatCivilTime(++second));
EXPECT_EQ("2015-01-02T03:04:07", absl::FormatCivilTime(second--));
EXPECT_EQ("2015-01-02T03:04:05", absl::FormatCivilTime(--second));
absl::CivilMinute minute(2015, 1, 2, 3, 4);
EXPECT_EQ("2015-01-02T03:05", absl::FormatCivilTime(minute += 1));
EXPECT_EQ("2015-01-02T03:06", absl::FormatCivilTime(minute + 1));
EXPECT_EQ("2015-01-02T03:07", absl::FormatCivilTime(2 + minute));
EXPECT_EQ("2015-01-02T03:04", absl::FormatCivilTime(minute - 1));
EXPECT_EQ("2015-01-02T03:04", absl::FormatCivilTime(minute -= 1));
EXPECT_EQ("2015-01-02T03:04", absl::FormatCivilTime(minute++));
EXPECT_EQ("2015-01-02T03:06", absl::FormatCivilTime(++minute));
EXPECT_EQ("2015-01-02T03:06", absl::FormatCivilTime(minute--));
EXPECT_EQ("2015-01-02T03:04", absl::FormatCivilTime(--minute));
absl::CivilHour hour(2015, 1, 2, 3);
EXPECT_EQ("2015-01-02T04", absl::FormatCivilTime(hour += 1));
EXPECT_EQ("2015-01-02T05", absl::FormatCivilTime(hour + 1));
EXPECT_EQ("2015-01-02T06", absl::FormatCivilTime(2 + hour));
EXPECT_EQ("2015-01-02T03", absl::FormatCivilTime(hour - 1));
EXPECT_EQ("2015-01-02T03", absl::FormatCivilTime(hour -= 1));
EXPECT_EQ("2015-01-02T03", absl::FormatCivilTime(hour++));
EXPECT_EQ("2015-01-02T05", absl::FormatCivilTime(++hour));
EXPECT_EQ("2015-01-02T05", absl::FormatCivilTime(hour--));
EXPECT_EQ("2015-01-02T03", absl::FormatCivilTime(--hour));
absl::CivilDay day(2015, 1, 2);
EXPECT_EQ("2015-01-03", absl::FormatCivilTime(day += 1));
EXPECT_EQ("2015-01-04", absl::FormatCivilTime(day + 1));
EXPECT_EQ("2015-01-05", absl::FormatCivilTime(2 + day));
EXPECT_EQ("2015-01-02", absl::FormatCivilTime(day - 1));
EXPECT_EQ("2015-01-02", absl::FormatCivilTime(day -= 1));
EXPECT_EQ("2015-01-02", absl::FormatCivilTime(day++));
EXPECT_EQ("2015-01-04", absl::FormatCivilTime(++day));
EXPECT_EQ("2015-01-04", absl::FormatCivilTime(day--));
EXPECT_EQ("2015-01-02", absl::FormatCivilTime(--day));
absl::CivilMonth month(2015, 1);
EXPECT_EQ("2015-02", absl::FormatCivilTime(month += 1));
EXPECT_EQ("2015-03", absl::FormatCivilTime(month + 1));
EXPECT_EQ("2015-04", absl::FormatCivilTime(2 + month));
EXPECT_EQ("2015-01", absl::FormatCivilTime(month - 1));
EXPECT_EQ("2015-01", absl::FormatCivilTime(month -= 1));
EXPECT_EQ("2015-01", absl::FormatCivilTime(month++));
EXPECT_EQ("2015-03", absl::FormatCivilTime(++month));
EXPECT_EQ("2015-03", absl::FormatCivilTime(month--));
EXPECT_EQ("2015-01", absl::FormatCivilTime(--month));
absl::CivilYear year(2015);
EXPECT_EQ("2016", absl::FormatCivilTime(year += 1));
EXPECT_EQ("2017", absl::FormatCivilTime(year + 1));
EXPECT_EQ("2018", absl::FormatCivilTime(2 + year));
EXPECT_EQ("2015", absl::FormatCivilTime(year - 1));
EXPECT_EQ("2015", absl::FormatCivilTime(year -= 1));
EXPECT_EQ("2015", absl::FormatCivilTime(year++));
EXPECT_EQ("2017", absl::FormatCivilTime(++year));
EXPECT_EQ("2017", absl::FormatCivilTime(year--));
EXPECT_EQ("2015", absl::FormatCivilTime(--year));
}
TEST(CivilTime, ArithmeticLimits) {
const int kIntMax = std::numeric_limits<int>::max();
const int kIntMin = std::numeric_limits<int>::min();
absl::CivilSecond second(1970, 1, 1, 0, 0, 0);
second += kIntMax;
EXPECT_EQ("2038-01-19T03:14:07", absl::FormatCivilTime(second));
second -= kIntMax;
EXPECT_EQ("1970-01-01T00:00:00", absl::FormatCivilTime(second));
second += kIntMin;
EXPECT_EQ("1901-12-13T20:45:52", absl::FormatCivilTime(second));
second -= kIntMin;
EXPECT_EQ("1970-01-01T00:00:00", absl::FormatCivilTime(second));
absl::CivilMinute minute(1970, 1, 1, 0, 0);
minute += kIntMax;
EXPECT_EQ("6053-01-23T02:07", absl::FormatCivilTime(minute));
minute -= kIntMax;
EXPECT_EQ("1970-01-01T00:00", absl::FormatCivilTime(minute));
minute += kIntMin;
EXPECT_EQ("-2114-12-08T21:52", absl::FormatCivilTime(minute));
minute -= kIntMin;
EXPECT_EQ("1970-01-01T00:00", absl::FormatCivilTime(minute));
absl::CivilHour hour(1970, 1, 1, 0);
hour += kIntMax;
EXPECT_EQ("246953-10-09T07", absl::FormatCivilTime(hour));
hour -= kIntMax;
EXPECT_EQ("1970-01-01T00", absl::FormatCivilTime(hour));
hour += kIntMin;
EXPECT_EQ("-243014-03-24T16", absl::FormatCivilTime(hour));
hour -= kIntMin;
EXPECT_EQ("1970-01-01T00", absl::FormatCivilTime(hour));
absl::CivilDay day(1970, 1, 1);
day += kIntMax;
EXPECT_EQ("5881580-07-11", absl::FormatCivilTime(day));
day -= kIntMax;
EXPECT_EQ("1970-01-01", absl::FormatCivilTime(day));
day += kIntMin;
EXPECT_EQ("-5877641-06-23", absl::FormatCivilTime(day));
day -= kIntMin;
EXPECT_EQ("1970-01-01", absl::FormatCivilTime(day));
absl::CivilMonth month(1970, 1);
month += kIntMax;
EXPECT_EQ("178958940-08", absl::FormatCivilTime(month));
month -= kIntMax;
EXPECT_EQ("1970-01", absl::FormatCivilTime(month));
month += kIntMin;
EXPECT_EQ("-178955001-05", absl::FormatCivilTime(month));
month -= kIntMin;
EXPECT_EQ("1970-01", absl::FormatCivilTime(month));
absl::CivilYear year(0);
year += kIntMax;
EXPECT_EQ("2147483647", absl::FormatCivilTime(year));
year -= kIntMax;
EXPECT_EQ("0", absl::FormatCivilTime(year));
year += kIntMin;
EXPECT_EQ("-2147483648", absl::FormatCivilTime(year));
year -= kIntMin;
EXPECT_EQ("0", absl::FormatCivilTime(year));
}
TEST(CivilTime, Difference) {
absl::CivilSecond second(2015, 1, 2, 3, 4, 5);
EXPECT_EQ(0, second - second);
EXPECT_EQ(10, (second + 10) - second);
EXPECT_EQ(-10, (second - 10) - second);
absl::CivilMinute minute(2015, 1, 2, 3, 4);
EXPECT_EQ(0, minute - minute);
EXPECT_EQ(10, (minute + 10) - minute);
EXPECT_EQ(-10, (minute - 10) - minute);
absl::CivilHour hour(2015, 1, 2, 3);
EXPECT_EQ(0, hour - hour);
EXPECT_EQ(10, (hour + 10) - hour);
EXPECT_EQ(-10, (hour - 10) - hour);
absl::CivilDay day(2015, 1, 2);
EXPECT_EQ(0, day - day);
EXPECT_EQ(10, (day + 10) - day);
EXPECT_EQ(-10, (day - 10) - day);
absl::CivilMonth month(2015, 1);
EXPECT_EQ(0, month - month);
EXPECT_EQ(10, (month + 10) - month);
EXPECT_EQ(-10, (month - 10) - month);
absl::CivilYear year(2015);
EXPECT_EQ(0, year - year);
EXPECT_EQ(10, (year + 10) - year);
EXPECT_EQ(-10, (year - 10) - year);
}
TEST(CivilTime, DifferenceLimits) {
const absl::civil_diff_t kDiffMax =
std::numeric_limits<absl::civil_diff_t>::max();
const absl::civil_diff_t kDiffMin =
std::numeric_limits<absl::civil_diff_t>::min();
// Check day arithmetic at the end of the year range.
const absl::CivilDay max_day(kDiffMax, 12, 31);
EXPECT_EQ(1, max_day - (max_day - 1));
EXPECT_EQ(-1, (max_day - 1) - max_day);
// Check day arithmetic at the start of the year range.
const absl::CivilDay min_day(kDiffMin, 1, 1);
EXPECT_EQ(1, (min_day + 1) - min_day);
EXPECT_EQ(-1, min_day - (min_day + 1));
// Check the limits of the return value.
const absl::CivilDay d1(1970, 1, 1);
const absl::CivilDay d2(25252734927768524, 7, 27);
EXPECT_EQ(kDiffMax, d2 - d1);
EXPECT_EQ(kDiffMin, d1 - (d2 + 1));
}
TEST(CivilTime, Properties) {
absl::CivilSecond ss(2015, 2, 3, 4, 5, 6);
EXPECT_EQ(2015, ss.year());
EXPECT_EQ(2, ss.month());
EXPECT_EQ(3, ss.day());
EXPECT_EQ(4, ss.hour());
EXPECT_EQ(5, ss.minute());
EXPECT_EQ(6, ss.second());
EXPECT_EQ(absl::Weekday::tuesday, absl::GetWeekday(ss));
EXPECT_EQ(34, absl::GetYearDay(ss));
absl::CivilMinute mm(2015, 2, 3, 4, 5, 6);
EXPECT_EQ(2015, mm.year());
EXPECT_EQ(2, mm.month());
EXPECT_EQ(3, mm.day());
EXPECT_EQ(4, mm.hour());
EXPECT_EQ(5, mm.minute());
EXPECT_EQ(0, mm.second());
EXPECT_EQ(absl::Weekday::tuesday, absl::GetWeekday(mm));
EXPECT_EQ(34, absl::GetYearDay(mm));
absl::CivilHour hh(2015, 2, 3, 4, 5, 6);
EXPECT_EQ(2015, hh.year());
EXPECT_EQ(2, hh.month());
EXPECT_EQ(3, hh.day());
EXPECT_EQ(4, hh.hour());
EXPECT_EQ(0, hh.minute());
EXPECT_EQ(0, hh.second());
EXPECT_EQ(absl::Weekday::tuesday, absl::GetWeekday(hh));
EXPECT_EQ(34, absl::GetYearDay(hh));
absl::CivilDay d(2015, 2, 3, 4, 5, 6);
EXPECT_EQ(2015, d.year());
EXPECT_EQ(2, d.month());
EXPECT_EQ(3, d.day());
EXPECT_EQ(0, d.hour());
EXPECT_EQ(0, d.minute());
EXPECT_EQ(0, d.second());
EXPECT_EQ(absl::Weekday::tuesday, absl::GetWeekday(d));
EXPECT_EQ(34, absl::GetYearDay(d));
absl::CivilMonth m(2015, 2, 3, 4, 5, 6);
EXPECT_EQ(2015, m.year());
EXPECT_EQ(2, m.month());
EXPECT_EQ(1, m.day());
EXPECT_EQ(0, m.hour());
EXPECT_EQ(0, m.minute());
EXPECT_EQ(0, m.second());
EXPECT_EQ(absl::Weekday::sunday, absl::GetWeekday(m));
EXPECT_EQ(32, absl::GetYearDay(m));
absl::CivilYear y(2015, 2, 3, 4, 5, 6);
EXPECT_EQ(2015, y.year());
EXPECT_EQ(1, y.month());
EXPECT_EQ(1, y.day());
EXPECT_EQ(0, y.hour());
EXPECT_EQ(0, y.minute());
EXPECT_EQ(0, y.second());
EXPECT_EQ(absl::Weekday::thursday, absl::GetWeekday(y));
EXPECT_EQ(1, absl::GetYearDay(y));
}
TEST(CivilTime, Format) {
absl::CivilSecond ss;
EXPECT_EQ("1970-01-01T00:00:00", absl::FormatCivilTime(ss));
absl::CivilMinute mm;
EXPECT_EQ("1970-01-01T00:00", absl::FormatCivilTime(mm));
absl::CivilHour hh;
EXPECT_EQ("1970-01-01T00", absl::FormatCivilTime(hh));
absl::CivilDay d;
EXPECT_EQ("1970-01-01", absl::FormatCivilTime(d));
absl::CivilMonth m;
EXPECT_EQ("1970-01", absl::FormatCivilTime(m));
absl::CivilYear y;
EXPECT_EQ("1970", absl::FormatCivilTime(y));
}
TEST(CivilTime, Parse) {
absl::CivilSecond ss;
absl::CivilMinute mm;
absl::CivilHour hh;
absl::CivilDay d;
absl::CivilMonth m;
absl::CivilYear y;
// CivilSecond OK; others fail
EXPECT_TRUE(absl::ParseCivilTime("2015-01-02T03:04:05", &ss));
EXPECT_EQ("2015-01-02T03:04:05", absl::FormatCivilTime(ss));
EXPECT_FALSE(absl::ParseCivilTime("2015-01-02T03:04:05", &mm));
EXPECT_FALSE(absl::ParseCivilTime("2015-01-02T03:04:05", &hh));
EXPECT_FALSE(absl::ParseCivilTime("2015-01-02T03:04:05", &d));
EXPECT_FALSE(absl::ParseCivilTime("2015-01-02T03:04:05", &m));
EXPECT_FALSE(absl::ParseCivilTime("2015-01-02T03:04:05", &y));
// CivilMinute OK; others fail
EXPECT_FALSE(absl::ParseCivilTime("2015-01-02T03:04", &ss));
EXPECT_TRUE(absl::ParseCivilTime("2015-01-02T03:04", &mm));
EXPECT_EQ("2015-01-02T03:04", absl::FormatCivilTime(mm));
EXPECT_FALSE(absl::ParseCivilTime("2015-01-02T03:04", &hh));
EXPECT_FALSE(absl::ParseCivilTime("2015-01-02T03:04", &d));
EXPECT_FALSE(absl::ParseCivilTime("2015-01-02T03:04", &m));
EXPECT_FALSE(absl::ParseCivilTime("2015-01-02T03:04", &y));
// CivilHour OK; others fail
EXPECT_FALSE(absl::ParseCivilTime("2015-01-02T03", &ss));
EXPECT_FALSE(absl::ParseCivilTime("2015-01-02T03", &mm));
EXPECT_TRUE(absl::ParseCivilTime("2015-01-02T03", &hh));
EXPECT_EQ("2015-01-02T03", absl::FormatCivilTime(hh));
EXPECT_FALSE(absl::ParseCivilTime("2015-01-02T03", &d));
EXPECT_FALSE(absl::ParseCivilTime("2015-01-02T03", &m));
EXPECT_FALSE(absl::ParseCivilTime("2015-01-02T03", &y));
// CivilDay OK; others fail
EXPECT_FALSE(absl::ParseCivilTime("2015-01-02", &ss));
EXPECT_FALSE(absl::ParseCivilTime("2015-01-02", &mm));
EXPECT_FALSE(absl::ParseCivilTime("2015-01-02", &hh));
EXPECT_TRUE(absl::ParseCivilTime("2015-01-02", &d));
EXPECT_EQ("2015-01-02", absl::FormatCivilTime(d));
EXPECT_FALSE(absl::ParseCivilTime("2015-01-02", &m));
EXPECT_FALSE(absl::ParseCivilTime("2015-01-02", &y));
// CivilMonth OK; others fail
EXPECT_FALSE(absl::ParseCivilTime("2015-01", &ss));
EXPECT_FALSE(absl::ParseCivilTime("2015-01", &mm));
EXPECT_FALSE(absl::ParseCivilTime("2015-01", &hh));
EXPECT_FALSE(absl::ParseCivilTime("2015-01", &d));
EXPECT_TRUE(absl::ParseCivilTime("2015-01", &m));
EXPECT_EQ("2015-01", absl::FormatCivilTime(m));
EXPECT_FALSE(absl::ParseCivilTime("2015-01", &y));
// CivilYear OK; others fail
EXPECT_FALSE(absl::ParseCivilTime("2015", &ss));
EXPECT_FALSE(absl::ParseCivilTime("2015", &mm));
EXPECT_FALSE(absl::ParseCivilTime("2015", &hh));
EXPECT_FALSE(absl::ParseCivilTime("2015", &d));
EXPECT_FALSE(absl::ParseCivilTime("2015", &m));
EXPECT_TRUE(absl::ParseCivilTime("2015", &y));
EXPECT_EQ("2015", absl::FormatCivilTime(y));
}
TEST(CivilTime, FormatAndParseLenient) {
absl::CivilSecond ss;
EXPECT_EQ("1970-01-01T00:00:00", absl::FormatCivilTime(ss));
absl::CivilMinute mm;
EXPECT_EQ("1970-01-01T00:00", absl::FormatCivilTime(mm));
absl::CivilHour hh;
EXPECT_EQ("1970-01-01T00", absl::FormatCivilTime(hh));
absl::CivilDay d;
EXPECT_EQ("1970-01-01", absl::FormatCivilTime(d));
absl::CivilMonth m;
EXPECT_EQ("1970-01", absl::FormatCivilTime(m));
absl::CivilYear y;
EXPECT_EQ("1970", absl::FormatCivilTime(y));
EXPECT_TRUE(absl::ParseLenientCivilTime("2015-01-02T03:04:05", &ss));
EXPECT_EQ("2015-01-02T03:04:05", absl::FormatCivilTime(ss));
EXPECT_TRUE(absl::ParseLenientCivilTime("2015-01-02T03:04:05", &mm));
EXPECT_EQ("2015-01-02T03:04", absl::FormatCivilTime(mm));
EXPECT_TRUE(absl::ParseLenientCivilTime("2015-01-02T03:04:05", &hh));
EXPECT_EQ("2015-01-02T03", absl::FormatCivilTime(hh));
EXPECT_TRUE(absl::ParseLenientCivilTime("2015-01-02T03:04:05", &d));
EXPECT_EQ("2015-01-02", absl::FormatCivilTime(d));
EXPECT_TRUE(absl::ParseLenientCivilTime("2015-01-02T03:04:05", &m));
EXPECT_EQ("2015-01", absl::FormatCivilTime(m));
EXPECT_TRUE(absl::ParseLenientCivilTime("2015-01-02T03:04:05", &y));
EXPECT_EQ("2015", absl::FormatCivilTime(y));
}
TEST(CivilTime, ParseEdgeCases) {
absl::CivilSecond ss;
EXPECT_TRUE(
absl::ParseLenientCivilTime("9223372036854775807-12-31T23:59:59", &ss));
EXPECT_EQ("9223372036854775807-12-31T23:59:59", absl::FormatCivilTime(ss));
EXPECT_TRUE(
absl::ParseLenientCivilTime("-9223372036854775808-01-01T00:00:00", &ss));
EXPECT_EQ("-9223372036854775808-01-01T00:00:00", absl::FormatCivilTime(ss));
absl::CivilMinute mm;
EXPECT_TRUE(
absl::ParseLenientCivilTime("9223372036854775807-12-31T23:59", &mm));
EXPECT_EQ("9223372036854775807-12-31T23:59", absl::FormatCivilTime(mm));
EXPECT_TRUE(
absl::ParseLenientCivilTime("-9223372036854775808-01-01T00:00", &mm));
EXPECT_EQ("-9223372036854775808-01-01T00:00", absl::FormatCivilTime(mm));
absl::CivilHour hh;
EXPECT_TRUE(
absl::ParseLenientCivilTime("9223372036854775807-12-31T23", &hh));
EXPECT_EQ("9223372036854775807-12-31T23", absl::FormatCivilTime(hh));
EXPECT_TRUE(
absl::ParseLenientCivilTime("-9223372036854775808-01-01T00", &hh));
EXPECT_EQ("-9223372036854775808-01-01T00", absl::FormatCivilTime(hh));
absl::CivilDay d;
EXPECT_TRUE(absl::ParseLenientCivilTime("9223372036854775807-12-31", &d));
EXPECT_EQ("9223372036854775807-12-31", absl::FormatCivilTime(d));
EXPECT_TRUE(absl::ParseLenientCivilTime("-9223372036854775808-01-01", &d));
EXPECT_EQ("-9223372036854775808-01-01", absl::FormatCivilTime(d));
absl::CivilMonth m;
EXPECT_TRUE(absl::ParseLenientCivilTime("9223372036854775807-12", &m));
EXPECT_EQ("9223372036854775807-12", absl::FormatCivilTime(m));
EXPECT_TRUE(absl::ParseLenientCivilTime("-9223372036854775808-01", &m));
EXPECT_EQ("-9223372036854775808-01", absl::FormatCivilTime(m));
absl::CivilYear y;
EXPECT_TRUE(absl::ParseLenientCivilTime("9223372036854775807", &y));
EXPECT_EQ("9223372036854775807", absl::FormatCivilTime(y));
EXPECT_TRUE(absl::ParseLenientCivilTime("-9223372036854775808", &y));
EXPECT_EQ("-9223372036854775808", absl::FormatCivilTime(y));
// Tests some valid, but interesting, cases
EXPECT_TRUE(absl::ParseLenientCivilTime("0", &ss)) << ss;
EXPECT_EQ(absl::CivilYear(0), ss);
EXPECT_TRUE(absl::ParseLenientCivilTime("0-1", &ss)) << ss;
EXPECT_EQ(absl::CivilMonth(0, 1), ss);
EXPECT_TRUE(absl::ParseLenientCivilTime(" 2015 ", &ss)) << ss;
EXPECT_EQ(absl::CivilYear(2015), ss);
EXPECT_TRUE(absl::ParseLenientCivilTime(" 2015-6 ", &ss)) << ss;
EXPECT_EQ(absl::CivilMonth(2015, 6), ss);
EXPECT_TRUE(absl::ParseLenientCivilTime("2015-6-7", &ss)) << ss;
EXPECT_EQ(absl::CivilDay(2015, 6, 7), ss);
EXPECT_TRUE(absl::ParseLenientCivilTime(" 2015-6-7 ", &ss)) << ss;
EXPECT_EQ(absl::CivilDay(2015, 6, 7), ss);
EXPECT_TRUE(absl::ParseLenientCivilTime("2015-06-07T10:11:12 ", &ss)) << ss;
EXPECT_EQ(absl::CivilSecond(2015, 6, 7, 10, 11, 12), ss);
EXPECT_TRUE(absl::ParseLenientCivilTime(" 2015-06-07T10:11:12 ", &ss)) << ss;
EXPECT_EQ(absl::CivilSecond(2015, 6, 7, 10, 11, 12), ss);
EXPECT_TRUE(absl::ParseLenientCivilTime("-01-01", &ss)) << ss;
EXPECT_EQ(absl::CivilMonth(-1, 1), ss);
// Tests some invalid cases
EXPECT_FALSE(absl::ParseLenientCivilTime("01-01-2015", &ss)) << ss;
EXPECT_FALSE(absl::ParseLenientCivilTime("2015-", &ss)) << ss;
EXPECT_FALSE(absl::ParseLenientCivilTime("0xff-01", &ss)) << ss;
EXPECT_FALSE(absl::ParseLenientCivilTime("2015-02-30T04:05:06", &ss)) << ss;
EXPECT_FALSE(absl::ParseLenientCivilTime("2015-02-03T04:05:96", &ss)) << ss;
EXPECT_FALSE(absl::ParseLenientCivilTime("X2015-02-03T04:05:06", &ss)) << ss;
EXPECT_FALSE(absl::ParseLenientCivilTime("2015-02-03T04:05:003", &ss)) << ss;
EXPECT_FALSE(absl::ParseLenientCivilTime("2015 -02-03T04:05:06", &ss)) << ss;
EXPECT_FALSE(absl::ParseLenientCivilTime("2015-02-03-04:05:06", &ss)) << ss;
EXPECT_FALSE(absl::ParseLenientCivilTime("2015:02:03T04-05-06", &ss)) << ss;
EXPECT_FALSE(absl::ParseLenientCivilTime("9223372036854775808", &y)) << y;
}
TEST(CivilTime, OutputStream) {
absl::CivilSecond cs(2016, 2, 3, 4, 5, 6);
{
std::stringstream ss;
ss << std::left << std::setfill('.');
ss << std::setw(3) << 'X';
ss << std::setw(21) << absl::CivilYear(cs);
ss << std::setw(3) << 'X';
EXPECT_EQ("X..2016.................X..", ss.str());
}
{
std::stringstream ss;
ss << std::left << std::setfill('.');
ss << std::setw(3) << 'X';
ss << std::setw(21) << absl::CivilMonth(cs);
ss << std::setw(3) << 'X';
EXPECT_EQ("X..2016-02..............X..", ss.str());
}
{
std::stringstream ss;
ss << std::left << std::setfill('.');
ss << std::setw(3) << 'X';
ss << std::setw(21) << absl::CivilDay(cs);
ss << std::setw(3) << 'X';
EXPECT_EQ("X..2016-02-03...........X..", ss.str());
}
{
std::stringstream ss;
ss << std::left << std::setfill('.');
ss << std::setw(3) << 'X';
ss << std::setw(21) << absl::CivilHour(cs);
ss << std::setw(3) << 'X';
EXPECT_EQ("X..2016-02-03T04........X..", ss.str());
}
{
std::stringstream ss;
ss << std::left << std::setfill('.');
ss << std::setw(3) << 'X';
ss << std::setw(21) << absl::CivilMinute(cs);
ss << std::setw(3) << 'X';
EXPECT_EQ("X..2016-02-03T04:05.....X..", ss.str());
}
{
std::stringstream ss;
ss << std::left << std::setfill('.');
ss << std::setw(3) << 'X';
ss << std::setw(21) << absl::CivilSecond(cs);
ss << std::setw(3) << 'X';
EXPECT_EQ("X..2016-02-03T04:05:06..X..", ss.str());
}
{
std::stringstream ss;
ss << std::left << std::setfill('.');
ss << std::setw(3) << 'X';
ss << std::setw(21) << absl::Weekday::wednesday;
ss << std::setw(3) << 'X';
EXPECT_EQ("X..Wednesday............X..", ss.str());
}
}
TEST(CivilTime, Weekday) {
absl::CivilDay d(1970, 1, 1);
EXPECT_EQ(absl::Weekday::thursday, absl::GetWeekday(d)) << d;
// We used to get this wrong for years < -30.
d = absl::CivilDay(-31, 12, 24);
EXPECT_EQ(absl::Weekday::wednesday, absl::GetWeekday(d)) << d;
}
TEST(CivilTime, NextPrevWeekday) {
// Jan 1, 1970 was a Thursday.
const absl::CivilDay thursday(1970, 1, 1);
// Thursday -> Thursday
absl::CivilDay d = absl::NextWeekday(thursday, absl::Weekday::thursday);
EXPECT_EQ(7, d - thursday) << d;
EXPECT_EQ(d - 14, absl::PrevWeekday(thursday, absl::Weekday::thursday));
// Thursday -> Friday
d = absl::NextWeekday(thursday, absl::Weekday::friday);
EXPECT_EQ(1, d - thursday) << d;
EXPECT_EQ(d - 7, absl::PrevWeekday(thursday, absl::Weekday::friday));
// Thursday -> Saturday
d = absl::NextWeekday(thursday, absl::Weekday::saturday);
EXPECT_EQ(2, d - thursday) << d;
EXPECT_EQ(d - 7, absl::PrevWeekday(thursday, absl::Weekday::saturday));
// Thursday -> Sunday
d = absl::NextWeekday(thursday, absl::Weekday::sunday);
EXPECT_EQ(3, d - thursday) << d;
EXPECT_EQ(d - 7, absl::PrevWeekday(thursday, absl::Weekday::sunday));
// Thursday -> Monday
d = absl::NextWeekday(thursday, absl::Weekday::monday);
EXPECT_EQ(4, d - thursday) << d;
EXPECT_EQ(d - 7, absl::PrevWeekday(thursday, absl::Weekday::monday));
// Thursday -> Tuesday
d = absl::NextWeekday(thursday, absl::Weekday::tuesday);
EXPECT_EQ(5, d - thursday) << d;
EXPECT_EQ(d - 7, absl::PrevWeekday(thursday, absl::Weekday::tuesday));
// Thursday -> Wednesday
d = absl::NextWeekday(thursday, absl::Weekday::wednesday);
EXPECT_EQ(6, d - thursday) << d;
EXPECT_EQ(d - 7, absl::PrevWeekday(thursday, absl::Weekday::wednesday));
}
// NOTE: Run this with --copt=-ftrapv to detect overflow problems.
TEST(CivilTime, DifferenceWithHugeYear) {
absl::CivilDay d1(9223372036854775807, 1, 1);
absl::CivilDay d2(9223372036854775807, 12, 31);
EXPECT_EQ(364, d2 - d1);
d1 = absl::CivilDay(-9223372036854775807 - 1, 1, 1);
d2 = absl::CivilDay(-9223372036854775807 - 1, 12, 31);
EXPECT_EQ(365, d2 - d1);
// Check the limits of the return value at the end of the year range.
d1 = absl::CivilDay(9223372036854775807, 1, 1);
d2 = absl::CivilDay(9198119301927009252, 6, 6);
EXPECT_EQ(9223372036854775807, d1 - d2);
d2 = d2 - 1;
EXPECT_EQ(-9223372036854775807 - 1, d2 - d1);
// Check the limits of the return value at the start of the year range.
d1 = absl::CivilDay(-9223372036854775807 - 1, 1, 1);
d2 = absl::CivilDay(-9198119301927009254, 7, 28);
EXPECT_EQ(9223372036854775807, d2 - d1);
d2 = d2 + 1;
EXPECT_EQ(-9223372036854775807 - 1, d1 - d2);
// Check the limits of the return value from either side of year 0.
d1 = absl::CivilDay(-12626367463883278, 9, 3);
d2 = absl::CivilDay(12626367463883277, 3, 28);
EXPECT_EQ(9223372036854775807, d2 - d1);
d2 = d2 + 1;
EXPECT_EQ(-9223372036854775807 - 1, d1 - d2);
}
// NOTE: Run this with --copt=-ftrapv to detect overflow problems.
TEST(CivilTime, DifferenceNoIntermediateOverflow) {
// The difference up to the minute field would be below the minimum
// int64_t, but the 52 extra seconds brings us back to the minimum.
absl::CivilSecond s1(-292277022657, 1, 27, 8, 29 - 1, 52);
absl::CivilSecond s2(1970, 1, 1, 0, 0 - 1, 0);
EXPECT_EQ(-9223372036854775807 - 1, s1 - s2);
// The difference up to the minute field would be above the maximum
// int64_t, but the -53 extra seconds brings us back to the maximum.
s1 = absl::CivilSecond(292277026596, 12, 4, 15, 30, 7 - 7);
s2 = absl::CivilSecond(1970, 1, 1, 0, 0, 0 - 7);
EXPECT_EQ(9223372036854775807, s1 - s2);
}
TEST(CivilTime, NormalizeSimpleOverflow) {
absl::CivilSecond cs;
cs = absl::CivilSecond(2013, 11, 15, 16, 32, 59 + 1);
EXPECT_EQ("2013-11-15T16:33:00", absl::FormatCivilTime(cs));
cs = absl::CivilSecond(2013, 11, 15, 16, 59 + 1, 14);
EXPECT_EQ("2013-11-15T17:00:14", absl::FormatCivilTime(cs));
cs = absl::CivilSecond(2013, 11, 15, 23 + 1, 32, 14);
EXPECT_EQ("2013-11-16T00:32:14", absl::FormatCivilTime(cs));
cs = absl::CivilSecond(2013, 11, 30 + 1, 16, 32, 14);
EXPECT_EQ("2013-12-01T16:32:14", absl::FormatCivilTime(cs));
cs = absl::CivilSecond(2013, 12 + 1, 15, 16, 32, 14);
EXPECT_EQ("2014-01-15T16:32:14", absl::FormatCivilTime(cs));
}
TEST(CivilTime, NormalizeSimpleUnderflow) {
absl::CivilSecond cs;
cs = absl::CivilSecond(2013, 11, 15, 16, 32, 0 - 1);
EXPECT_EQ("2013-11-15T16:31:59", absl::FormatCivilTime(cs));
cs = absl::CivilSecond(2013, 11, 15, 16, 0 - 1, 14);
EXPECT_EQ("2013-11-15T15:59:14", absl::FormatCivilTime(cs));
cs = absl::CivilSecond(2013, 11, 15, 0 - 1, 32, 14);
EXPECT_EQ("2013-11-14T23:32:14", absl::FormatCivilTime(cs));
cs = absl::CivilSecond(2013, 11, 1 - 1, 16, 32, 14);
EXPECT_EQ("2013-10-31T16:32:14", absl::FormatCivilTime(cs));
cs = absl::CivilSecond(2013, 1 - 1, 15, 16, 32, 14);
EXPECT_EQ("2012-12-15T16:32:14", absl::FormatCivilTime(cs));
}
TEST(CivilTime, NormalizeMultipleOverflow) {
absl::CivilSecond cs(2013, 12, 31, 23, 59, 59 + 1);
EXPECT_EQ("2014-01-01T00:00:00", absl::FormatCivilTime(cs));
}
TEST(CivilTime, NormalizeMultipleUnderflow) {
absl::CivilSecond cs(2014, 1, 1, 0, 0, 0 - 1);
EXPECT_EQ("2013-12-31T23:59:59", absl::FormatCivilTime(cs));
}
TEST(CivilTime, NormalizeOverflowLimits) {
absl::CivilSecond cs;
const int kintmax = std::numeric_limits<int>::max();
cs = absl::CivilSecond(0, kintmax, kintmax, kintmax, kintmax, kintmax);
EXPECT_EQ("185085715-11-27T12:21:07", absl::FormatCivilTime(cs));
const int kintmin = std::numeric_limits<int>::min();
cs = absl::CivilSecond(0, kintmin, kintmin, kintmin, kintmin, kintmin);
EXPECT_EQ("-185085717-10-31T10:37:52", absl::FormatCivilTime(cs));
}
TEST(CivilTime, NormalizeComplexOverflow) {
absl::CivilSecond cs;
cs = absl::CivilSecond(2013, 11, 15, 16, 32, 14 + 123456789);
EXPECT_EQ("2017-10-14T14:05:23", absl::FormatCivilTime(cs));
cs = absl::CivilSecond(2013, 11, 15, 16, 32 + 1234567, 14);
EXPECT_EQ("2016-03-22T00:39:14", absl::FormatCivilTime(cs));
cs = absl::CivilSecond(2013, 11, 15, 16 + 123456, 32, 14);
EXPECT_EQ("2027-12-16T16:32:14", absl::FormatCivilTime(cs));
cs = absl::CivilSecond(2013, 11, 15 + 1234, 16, 32, 14);
EXPECT_EQ("2017-04-02T16:32:14", absl::FormatCivilTime(cs));
cs = absl::CivilSecond(2013, 11 + 123, 15, 16, 32, 14);
EXPECT_EQ("2024-02-15T16:32:14", absl::FormatCivilTime(cs));
}
TEST(CivilTime, NormalizeComplexUnderflow) {
absl::CivilSecond cs;
cs = absl::CivilSecond(1999, 3, 0, 0, 0, 0); // year 400
EXPECT_EQ("1999-02-28T00:00:00", absl::FormatCivilTime(cs));
cs = absl::CivilSecond(2013, 11, 15, 16, 32, 14 - 123456789);
EXPECT_EQ("2009-12-17T18:59:05", absl::FormatCivilTime(cs));
cs = absl::CivilSecond(2013, 11, 15, 16, 32 - 1234567, 14);
EXPECT_EQ("2011-07-12T08:25:14", absl::FormatCivilTime(cs));
cs = absl::CivilSecond(2013, 11, 15, 16 - 123456, 32, 14);
EXPECT_EQ("1999-10-16T16:32:14", absl::FormatCivilTime(cs));
cs = absl::CivilSecond(2013, 11, 15 - 1234, 16, 32, 14);
EXPECT_EQ("2010-06-30T16:32:14", absl::FormatCivilTime(cs));
cs = absl::CivilSecond(2013, 11 - 123, 15, 16, 32, 14);
EXPECT_EQ("2003-08-15T16:32:14", absl::FormatCivilTime(cs));
}
TEST(CivilTime, NormalizeMishmash) {
absl::CivilSecond cs;
cs = absl::CivilSecond(2013, 11 - 123, 15 + 1234, 16 - 123456, 32 + 1234567,
14 - 123456789);
EXPECT_EQ("1991-05-09T03:06:05", absl::FormatCivilTime(cs));
cs = absl::CivilSecond(2013, 11 + 123, 15 - 1234, 16 + 123456, 32 - 1234567,
14 + 123456789);
EXPECT_EQ("2036-05-24T05:58:23", absl::FormatCivilTime(cs));
cs = absl::CivilSecond(2013, 11, -146097 + 1, 16, 32, 14);
EXPECT_EQ("1613-11-01T16:32:14", absl::FormatCivilTime(cs));
cs = absl::CivilSecond(2013, 11 + 400 * 12, -146097 + 1, 16, 32, 14);
EXPECT_EQ("2013-11-01T16:32:14", absl::FormatCivilTime(cs));
}
// Convert all the days from 1970-1-1 to 1970-1-146097 (aka 2369-12-31)
// and check that they normalize to the expected time. 146097 days span
// the 400-year Gregorian cycle used during normalization.
TEST(CivilTime, NormalizeAllTheDays) {
absl::CivilDay expected(1970, 1, 1);
for (int day = 1; day <= 146097; ++day) {
absl::CivilSecond cs(1970, 1, day, 0, 0, 0);
EXPECT_EQ(expected, cs);
++expected;
}
}
TEST(CivilTime, NormalizeWithHugeYear) {
absl::CivilMonth c(9223372036854775807, 1);
EXPECT_EQ("9223372036854775807-01", absl::FormatCivilTime(c));
c = c - 1; // Causes normalization
EXPECT_EQ("9223372036854775806-12", absl::FormatCivilTime(c));
c = absl::CivilMonth(-9223372036854775807 - 1, 1);
EXPECT_EQ("-9223372036854775808-01", absl::FormatCivilTime(c));
c = c + 12; // Causes normalization
EXPECT_EQ("-9223372036854775807-01", absl::FormatCivilTime(c));
}
TEST(CivilTime, LeapYears) {
const absl::CivilSecond s1(2013, 2, 28 + 1, 0, 0, 0);
EXPECT_EQ("2013-03-01T00:00:00", absl::FormatCivilTime(s1));
const absl::CivilSecond s2(2012, 2, 28 + 1, 0, 0, 0);
EXPECT_EQ("2012-02-29T00:00:00", absl::FormatCivilTime(s2));
const absl::CivilSecond s3(1900, 2, 28 + 1, 0, 0, 0);
EXPECT_EQ("1900-03-01T00:00:00", absl::FormatCivilTime(s3));
const struct {
int year;
int days;
struct {
int month;
int day;
} leap_day; // The date of the day after Feb 28.
} kLeapYearTable[]{
{1900, 365, {3, 1}},
{1999, 365, {3, 1}},
{2000, 366, {2, 29}}, // leap year
{2001, 365, {3, 1}},
{2002, 365, {3, 1}},
{2003, 365, {3, 1}},
{2004, 366, {2, 29}}, // leap year
{2005, 365, {3, 1}},
{2006, 365, {3, 1}},
{2007, 365, {3, 1}},
{2008, 366, {2, 29}}, // leap year
{2009, 365, {3, 1}},
{2100, 365, {3, 1}},
};
for (int i = 0; i < ABSL_ARRAYSIZE(kLeapYearTable); ++i) {
const int y = kLeapYearTable[i].year;
const int m = kLeapYearTable[i].leap_day.month;
const int d = kLeapYearTable[i].leap_day.day;
const int n = kLeapYearTable[i].days;
// Tests incrementing through the leap day.
const absl::CivilDay feb28(y, 2, 28);
const absl::CivilDay next_day = feb28 + 1;
EXPECT_EQ(m, next_day.month());
EXPECT_EQ(d, next_day.day());
// Tests difference in days of leap years.
const absl::CivilYear year(feb28);
const absl::CivilYear next_year = year + 1;
EXPECT_EQ(n, absl::CivilDay(next_year) - absl::CivilDay(year));
}
}
TEST(CivilTime, FirstThursdayInMonth) {
const absl::CivilDay nov1(2014, 11, 1);
const absl::CivilDay thursday =
absl::NextWeekday(nov1 - 1, absl::Weekday::thursday);
EXPECT_EQ("2014-11-06", absl::FormatCivilTime(thursday));
// Bonus: Date of Thanksgiving in the United States
// Rule: Fourth Thursday of November
const absl::CivilDay thanksgiving = thursday + 7 * 3;
EXPECT_EQ("2014-11-27", absl::FormatCivilTime(thanksgiving));
}
TEST(CivilTime, DocumentationExample) {
absl::CivilSecond second(2015, 6, 28, 1, 2, 3); // 2015-06-28 01:02:03
absl::CivilMinute minute(second); // 2015-06-28 01:02:00
absl::CivilDay day(minute); // 2015-06-28 00:00:00
second -= 1; // 2015-06-28 01:02:02
--second; // 2015-06-28 01:02:01
EXPECT_EQ(minute, second - 1); // Comparison between types
EXPECT_LT(minute, second);
// int diff = second - minute; // ERROR: Mixed types, won't compile
absl::CivilDay june_1(2015, 6, 1); // Pass fields to c'tor.
int diff = day - june_1; // Num days between 'day' and June 1
EXPECT_EQ(27, diff);
// Fields smaller than alignment are floored to their minimum value.
absl::CivilDay day_floor(2015, 1, 2, 9, 9, 9);
EXPECT_EQ(0, day_floor.hour()); // 09:09:09 is floored
EXPECT_EQ(absl::CivilDay(2015, 1, 2), day_floor);
// Unspecified fields default to their minium value
absl::CivilDay day_default(2015); // Defaults to Jan 1
EXPECT_EQ(absl::CivilDay(2015, 1, 1), day_default);
// Iterates all the days of June.
absl::CivilMonth june(day); // CivilDay -> CivilMonth
absl::CivilMonth july = june + 1;
for (absl::CivilDay day = june_1; day < july; ++day) {
// ...
}
}
} // namespace