diff options
Diffstat (limited to 'src/mongo/db/query/datetime/date_time_support_test.cpp')
-rw-r--r-- | src/mongo/db/query/datetime/date_time_support_test.cpp | 315 |
1 files changed, 315 insertions, 0 deletions
diff --git a/src/mongo/db/query/datetime/date_time_support_test.cpp b/src/mongo/db/query/datetime/date_time_support_test.cpp index fba52b3e029..247ed2b8e2b 100644 --- a/src/mongo/db/query/datetime/date_time_support_test.cpp +++ b/src/mongo/db/query/datetime/date_time_support_test.cpp @@ -29,7 +29,9 @@ #include "mongo/platform/basic.h" +#include <limits> #include <sstream> +#include <timelib.h> #include "mongo/db/query/datetime/date_time_support.h" #include "mongo/unittest/unittest.h" @@ -1191,5 +1193,318 @@ TEST(DayOfWeek, DayNumber) { } } +// Time zones for testing 'dateDiff()'. +const TimeZone kNewYorkTimeZone = kDefaultTimeZoneDatabase.getTimeZone("America/New_York"); +const TimeZone kAustraliaEuclaTimeZone = + kDefaultTimeZoneDatabase.getTimeZone("Australia/Eucla"); // UTC offset +08:45 + +// Verifies 'dateDiff()' with TimeUnit::year. +TEST(DateDiff, Year) { + ASSERT_EQ(0, + dateDiff(kNewYorkTimeZone.createFromDateParts(2000, 12, 31, 23, 59, 59, 500), + kNewYorkTimeZone.createFromDateParts(2000, 12, 31, 23, 59, 59, 999), + TimeUnit::year, + kNewYorkTimeZone)); + ASSERT_EQ(1, + dateDiff(kNewYorkTimeZone.createFromDateParts(2000, 12, 31, 23, 59, 59, 500), + kNewYorkTimeZone.createFromDateParts(2001, 1, 1, 0, 0, 0, 0), + TimeUnit::year, + kNewYorkTimeZone)); + ASSERT_EQ(-1, + dateDiff(kNewYorkTimeZone.createFromDateParts(2001, 1, 1, 0, 0, 0, 0), + kNewYorkTimeZone.createFromDateParts(2000, 12, 31, 23, 59, 59, 500), + TimeUnit::year, + kNewYorkTimeZone)); + ASSERT_EQ(999, + dateDiff(kNewYorkTimeZone.createFromDateParts(1002, 1, 1, 0, 0, 0, 0), + kNewYorkTimeZone.createFromDateParts(2001, 1, 1, 0, 0, 0, 0), + TimeUnit::year, + kNewYorkTimeZone)); +} + +// Verifies 'dateDiff()' with TimeUnit::month. +TEST(DateDiff, Month) { + ASSERT_EQ(0, + dateDiff(kNewYorkTimeZone.createFromDateParts(2020, 2, 28, 23, 59, 59, 500), + kNewYorkTimeZone.createFromDateParts(2020, 2, 29, 23, 59, 59, 999), + TimeUnit::month, + kNewYorkTimeZone)); + ASSERT_EQ(1, + dateDiff(kNewYorkTimeZone.createFromDateParts(2020, 2, 29, 23, 59, 59, 999), + kNewYorkTimeZone.createFromDateParts(2020, 3, 1, 0, 0, 0, 0), + TimeUnit::month, + kNewYorkTimeZone)); + ASSERT_EQ(-14, + dateDiff(kNewYorkTimeZone.createFromDateParts(2010, 2, 28, 23, 59, 59, 999), + kNewYorkTimeZone.createFromDateParts(2008, 12, 31, 23, 59, 59, 500), + TimeUnit::month, + kNewYorkTimeZone)); + ASSERT_EQ(1500 * 12, + dateDiff(kNewYorkTimeZone.createFromDateParts(520, 3, 1, 0, 0, 0, 0), + kNewYorkTimeZone.createFromDateParts(2020, 3, 1, 0, 0, 0, 0), + TimeUnit::month, + kNewYorkTimeZone)); +} + +// Verifies 'dateDiff()' with TimeUnit::quarter. +TEST(DateDiff, Quarter) { + ASSERT_EQ(0, + dateDiff(kNewYorkTimeZone.createFromDateParts(2020, 1, 1, 0, 0, 0, 0), + kNewYorkTimeZone.createFromDateParts(2020, 3, 31, 23, 59, 59, 999), + TimeUnit::quarter, + kNewYorkTimeZone)); + ASSERT_EQ(1, + dateDiff(kNewYorkTimeZone.createFromDateParts(2020, 1, 1, 0, 0, 0, 0), + kNewYorkTimeZone.createFromDateParts(2020, 4, 1, 0, 0, 0, 0), + TimeUnit::quarter, + kNewYorkTimeZone)); + ASSERT_EQ(-2001, + dateDiff(kNewYorkTimeZone.createFromDateParts(2000, 12, 31, 23, 59, 59, 500), + kNewYorkTimeZone.createFromDateParts(1500, 9, 30, 23, 59, 59, 999), + TimeUnit::quarter, + kNewYorkTimeZone)); +} + +// Verifies 'dateDiff()' with TimeUnit::week. +TEST(DateDiff, Week) { + ASSERT_EQ(1, + dateDiff(kNewYorkTimeZone.createFromDateParts(2020, 11, 2, 0, 0, 0, 0), + kNewYorkTimeZone.createFromDateParts(2020, 11, 9, 0, 0, 0, 0), + TimeUnit::week, + kNewYorkTimeZone)); + ASSERT_EQ(1, + dateDiff(kNewYorkTimeZone.createFromDateParts(2020, 11, 2, 0, 0, 0, 0), + kNewYorkTimeZone.createFromDateParts(2020, 11, 15, 0, 0, 0, 0), + TimeUnit::week, + kNewYorkTimeZone)); + ASSERT_EQ(0, + dateDiff(kNewYorkTimeZone.createFromDateParts(2020, 11, 2, 0, 0, 0, 0), + kNewYorkTimeZone.createFromDateParts(2020, 11, 8, 0, 0, 0, 0), + TimeUnit::week, + kNewYorkTimeZone)); + ASSERT_EQ(0, + dateDiff(kNewYorkTimeZone.createFromDateParts(2020, 11, 2, 0, 0, 0, 0), + kNewYorkTimeZone.createFromDateParts(2020, 11, 2, 0, 0, 0, 0), + TimeUnit::week, + kNewYorkTimeZone)); + ASSERT_EQ(0, + dateDiff(kNewYorkTimeZone.createFromDateParts(2020, 11, 2, 0, 0, 0, 0), + kNewYorkTimeZone.createFromDateParts(2020, 11, 3, 0, 0, 0, 0), + TimeUnit::week, + kNewYorkTimeZone)); + ASSERT_EQ(1, + dateDiff(kNewYorkTimeZone.createFromDateParts(2020, 11, 8, 0, 0, 0, 0), + kNewYorkTimeZone.createFromDateParts(2020, 11, 9, 0, 0, 0, 0), + TimeUnit::week, + kNewYorkTimeZone)); + ASSERT_EQ(1, + dateDiff(kNewYorkTimeZone.createFromDateParts(2020, 11, 8, 0, 0, 0, 0), + kNewYorkTimeZone.createFromDateParts(2020, 11, 15, 0, 0, 0, 0), + TimeUnit::week, + kNewYorkTimeZone)); + ASSERT_EQ(-5, + dateDiff(kNewYorkTimeZone.createFromDateParts(2020, 11, 10, 0, 0, 0, 0), + kNewYorkTimeZone.createFromDateParts(2020, 10, 8, 0, 0, 0, 0), + TimeUnit::week, + kNewYorkTimeZone)); +} + +// Verifies 'dateDiff()' with TimeUnit::day. +TEST(DateDiff, Day) { + ASSERT_EQ(0, + dateDiff(kNewYorkTimeZone.createFromDateParts(2020, 11, 8, 0, 0, 0, 0), + kNewYorkTimeZone.createFromDateParts(2020, 11, 8, 23, 59, 59, 999), + TimeUnit::day, + kNewYorkTimeZone)); + ASSERT_EQ(1, + dateDiff(kNewYorkTimeZone.createFromDateParts(2020, 11, 8, 0, 0, 0, 0), + kNewYorkTimeZone.createFromDateParts(2020, 11, 9, 0, 0, 0, 0), + TimeUnit::day, + kNewYorkTimeZone)); + ASSERT_EQ(-1, + dateDiff(kNewYorkTimeZone.createFromDateParts(2020, 11, 9, 0, 0, 0, 0), + kNewYorkTimeZone.createFromDateParts(2020, 11, 8, 23, 59, 59, 999), + TimeUnit::day, + kNewYorkTimeZone)); + + // Verifies number of days in a year calculation. + ASSERT_EQ(369, + dateDiff(kNewYorkTimeZone.createFromDateParts(1999, 12, 30, 0, 0, 0, 0), + kNewYorkTimeZone.createFromDateParts(2001, 1, 2, 0, 0, 0, 0), + TimeUnit::day, + kNewYorkTimeZone)); + ASSERT_EQ(6575, + dateDiff(kNewYorkTimeZone.createFromDateParts(1583, 1, 1, 0, 0, 0, 0), + kNewYorkTimeZone.createFromDateParts(1601, 1, 1, 0, 0, 0, 0), + TimeUnit::day, + kNewYorkTimeZone)); + ASSERT_EQ(-6575, + dateDiff(kNewYorkTimeZone.createFromDateParts(1601, 1, 1, 0, 0, 0, 0), + kNewYorkTimeZone.createFromDateParts(1583, 1, 1, 0, 0, 0, 0), + TimeUnit::day, + kNewYorkTimeZone)); + ASSERT_EQ(29, + dateDiff(kNewYorkTimeZone.createFromDateParts(2004, 2, 10, 0, 0, 0, 0), + kNewYorkTimeZone.createFromDateParts(2004, 3, 10, 0, 0, 0, 0), + TimeUnit::day, + kNewYorkTimeZone)); + ASSERT_EQ(28, + dateDiff(kAustraliaEuclaTimeZone.createFromDateParts(2005, 2, 10, 0, 0, 0, 0), + kAustraliaEuclaTimeZone.createFromDateParts(2005, 3, 10, 0, 0, 0, 0), + TimeUnit::day, + kAustraliaEuclaTimeZone)); + + // Use timelib_day_of_year as an oracle to verify day calculations. + for (int year = -1000; year < 3000; ++year) { + int expectedNumberOfDays = timelib_day_of_year(year, 12, 31) + 1; + ASSERT_EQ(expectedNumberOfDays, + dateDiff(kNewYorkTimeZone.createFromDateParts(year, 2, 3, 0, 0, 0, 0), + kNewYorkTimeZone.createFromDateParts(year + 1, 2, 3, 0, 0, 0, 0), + TimeUnit::day, + kNewYorkTimeZone)); + } +} + +// Verifies 'dateDiff()' with TimeUnit::hour. +TEST(DateDiff, Hour) { + ASSERT_EQ(0, + dateDiff(kNewYorkTimeZone.createFromDateParts(2020, 11, 8, 1, 0, 0, 0), + kNewYorkTimeZone.createFromDateParts(2020, 11, 8, 1, 59, 59, 999), + TimeUnit::hour, + kNewYorkTimeZone)); + ASSERT_EQ(1, + dateDiff(kNewYorkTimeZone.createFromDateParts(2020, 11, 8, 1, 59, 59, 999), + kNewYorkTimeZone.createFromDateParts(2020, 11, 8, 2, 0, 0, 0), + TimeUnit::hour, + kNewYorkTimeZone)); + ASSERT_EQ(-25, + dateDiff(kNewYorkTimeZone.createFromDateParts(2020, 11, 10, 0, 0, 0, 0), + kNewYorkTimeZone.createFromDateParts(2020, 11, 8, 23, 59, 59, 999), + TimeUnit::hour, + kNewYorkTimeZone)); + + // Hour difference calculation in UTC offset +08:45 time zone. + ASSERT_EQ( + 1, + dateDiff( + kAustraliaEuclaTimeZone.createFromDateParts(2020, 11, 10, 20, 55, 0, 0) /*UTC 12:10*/, + kAustraliaEuclaTimeZone.createFromDateParts(2020, 11, 10, 21, 5, 0, 0) /*UTC 12:20*/, + TimeUnit::hour, + kAustraliaEuclaTimeZone)); + + // Test of transition from DST to standard time. + ASSERT_EQ(1, + dateDiff(kDefaultTimeZone.createFromDateParts( + 2020, 11, 1, 5, 0, 0, 0) /* America/New_York 1:00AM EDT (UTC-4)*/, + kDefaultTimeZone.createFromDateParts( + 2020, 11, 1, 6, 0, 0, 0) /* America/New_York 1:00AM EST (UTC-5)*/, + TimeUnit::hour, + kNewYorkTimeZone)); + ASSERT_EQ(-1, + dateDiff(kDefaultTimeZone.createFromDateParts( + 2020, 11, 1, 6, 0, 0, 0) /* America/New_York 1:00AM EST (UTC-5)*/, + kDefaultTimeZone.createFromDateParts( + 2020, 11, 1, 5, 0, 0, 0) /* America/New_York 1:00AM EDT (UTC-4)*/, + TimeUnit::hour, + kNewYorkTimeZone)); + + // Test of transition from standard time to DST. + ASSERT_EQ(1, + dateDiff(kDefaultTimeZone.createFromDateParts( + 2020, 3, 8, 6, 45, 0, 0) /* America/New_York 1:45AM EST (UTC-5)*/, + kDefaultTimeZone.createFromDateParts( + 2020, 3, 8, 7, 0, 0, 0) /* America/New_York 3:00AM EDT (UTC-4)*/, + TimeUnit::hour, + kNewYorkTimeZone)); + ASSERT_EQ(-1, + dateDiff(kDefaultTimeZone.createFromDateParts( + 2020, 3, 8, 7, 0, 0, 0) /* America/New_York 3:00AM EDT (UTC-4)*/, + kDefaultTimeZone.createFromDateParts( + 2020, 3, 8, 6, 45, 0, 0) /* America/New_York 1:45AM EST (UTC-5)*/, + TimeUnit::hour, + kNewYorkTimeZone)); + + // Longer period test. + ASSERT_EQ(17545, + dateDiff(kNewYorkTimeZone.createFromDateParts(1999, 1, 1, 0, 0, 0, 0), + kNewYorkTimeZone.createFromDateParts(2001, 1, 1, 1, 0, 0, 0), + TimeUnit::hour, + kNewYorkTimeZone)); +} + +// Verifies 'dateDiff()' with TimeUnit::minute. +TEST(DateDiff, Minute) { + ASSERT_EQ(0, + dateDiff(kNewYorkTimeZone.createFromDateParts(2020, 11, 8, 1, 30, 0, 0), + kNewYorkTimeZone.createFromDateParts(2020, 11, 8, 1, 30, 59, 999), + TimeUnit::minute, + kNewYorkTimeZone)); + ASSERT_EQ(1, + dateDiff(kNewYorkTimeZone.createFromDateParts(2020, 11, 8, 1, 30, 59, 999), + kNewYorkTimeZone.createFromDateParts(2020, 11, 8, 1, 31, 0, 0), + TimeUnit::minute, + kNewYorkTimeZone)); + ASSERT_EQ(-25, + dateDiff(kNewYorkTimeZone.createFromDateParts(2020, 11, 8, 1, 55, 0, 0), + kNewYorkTimeZone.createFromDateParts(2020, 11, 8, 1, 30, 59, 999), + TimeUnit::minute, + kNewYorkTimeZone)); + ASSERT_EQ(234047495, + dateDiff(kNewYorkTimeZone.createFromDateParts(1585, 11, 8, 1, 55, 0, 0), + kNewYorkTimeZone.createFromDateParts(2030, 11, 8, 1, 30, 59, 999), + TimeUnit::minute, + kNewYorkTimeZone)); +} + +// Verifies 'dateDiff()' with TimeUnit::second. +TEST(DateDiff, Second) { + ASSERT_EQ(0, + dateDiff(kNewYorkTimeZone.createFromDateParts(2020, 11, 8, 1, 30, 15, 0), + kNewYorkTimeZone.createFromDateParts(2020, 11, 8, 1, 30, 15, 999), + TimeUnit::second, + kNewYorkTimeZone)); + ASSERT_EQ(1, + dateDiff(kNewYorkTimeZone.createFromDateParts(2020, 11, 8, 1, 30, 15, 999), + kNewYorkTimeZone.createFromDateParts(2020, 11, 8, 1, 30, 16, 0), + TimeUnit::second, + kNewYorkTimeZone)); + ASSERT_EQ(-2401, + dateDiff(kNewYorkTimeZone.createFromDateParts(2020, 11, 8, 2, 10, 16, 999), + kNewYorkTimeZone.createFromDateParts(2020, 11, 8, 1, 30, 15, 999), + TimeUnit::second, + kNewYorkTimeZone)); + ASSERT_EQ(1604971816, + dateDiff(kDefaultTimeZone.createFromDateParts(1970, 1, 1, 0, 0, 0, 0), + kDefaultTimeZone.createFromDateParts(2020, 11, 10, 1, 30, 16, 0), + TimeUnit::second, + kNewYorkTimeZone)); +} + +// Verifies 'dateDiff()' with TimeUnit::millisecond. +TEST(DateDiff, Millisecond) { + ASSERT_EQ(100, + dateDiff(kNewYorkTimeZone.createFromDateParts(2020, 11, 8, 1, 30, 15, 0), + kNewYorkTimeZone.createFromDateParts(2020, 11, 8, 1, 30, 15, 100), + TimeUnit::millisecond, + kNewYorkTimeZone)); + ASSERT_EQ(-1500, + dateDiff(kNewYorkTimeZone.createFromDateParts(2020, 11, 8, 1, 30, 16, 500), + kNewYorkTimeZone.createFromDateParts(2020, 11, 8, 1, 30, 15, 0), + TimeUnit::millisecond, + kNewYorkTimeZone)); + ASSERT_EQ(1604971816000, + dateDiff(kDefaultTimeZone.createFromDateParts(1970, 1, 1, 0, 0, 0, 0), + kDefaultTimeZone.createFromDateParts(2020, 11, 10, 1, 30, 16, 0), + TimeUnit::millisecond, + kNewYorkTimeZone)); + + // Verifies numeric overflow handling. + ASSERT_THROWS_CODE(dateDiff(Date_t::fromMillisSinceEpoch(std::numeric_limits<long long>::min()), + Date_t::fromMillisSinceEpoch(std::numeric_limits<long long>::max()), + TimeUnit::millisecond, + kNewYorkTimeZone), + AssertionException, + 5166308); +} } // namespace } // namespace mongo |