| //===-- Unittests for mktime ----------------------------------------------===// | |
| // | |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| // See https://llvm.org/LICENSE.txt for license information. | |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| // | |
| //===----------------------------------------------------------------------===// | |
| #include "src/__support/CPP/limits.h" // INT_MAX | |
| #include "src/time/mktime.h" | |
| #include "src/time/time_constants.h" | |
| #include "test/UnitTest/ErrnoSetterMatcher.h" | |
| #include "test/UnitTest/Test.h" | |
| #include "test/src/time/TmHelper.h" | |
| #include "test/src/time/TmMatcher.h" | |
| using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails; | |
| using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds; | |
| using LIBC_NAMESPACE::time_constants::Month; | |
| #ifndef EOVERFLOW | |
| #define EOVERFLOW 0 | |
| #endif | |
| static inline constexpr int tm_year(int year) { | |
| return year - LIBC_NAMESPACE::time_constants::TIME_YEAR_BASE; | |
| } | |
| TEST(LlvmLibcMkTime, FailureSetsErrno) { | |
| struct tm tm_data{.tm_sec = INT_MAX, | |
| .tm_min = INT_MAX, | |
| .tm_hour = INT_MAX, | |
| .tm_mday = INT_MAX, | |
| .tm_mon = INT_MAX - 1, | |
| .tm_year = tm_year(INT_MAX), | |
| .tm_wday = 0, | |
| .tm_yday = 0, | |
| .tm_isdst = 0}; | |
| EXPECT_THAT(static_cast<int>(LIBC_NAMESPACE::mktime(&tm_data)), | |
| Fails(EOVERFLOW)); | |
| } | |
| TEST(LlvmLibcMkTime, InvalidSeconds) { | |
| { | |
| // -1 second from 1970-01-01 00:00:00 returns 1969-12-31 23:59:59. | |
| struct tm tm_data{.tm_sec = -1, | |
| .tm_min = 0, | |
| .tm_hour = 0, | |
| .tm_mday = 1, | |
| .tm_mon = Month::JANUARY, | |
| .tm_year = tm_year(1970), | |
| .tm_wday = 0, | |
| .tm_yday = 0, | |
| .tm_isdst = 0}; | |
| EXPECT_THAT(static_cast<int>(LIBC_NAMESPACE::mktime(&tm_data)), | |
| Succeeds(-1)); | |
| EXPECT_TM_EQ((tm{.tm_sec = 59, | |
| .tm_min = 59, | |
| .tm_hour = 23, | |
| .tm_mday = 31, | |
| .tm_mon = Month::DECEMBER, | |
| .tm_year = tm_year(1969), | |
| .tm_wday = 3, | |
| .tm_yday = 364, | |
| .tm_isdst = 0}), | |
| tm_data); | |
| } | |
| { | |
| // 60 seconds from 1970-01-01 00:00:00 returns 1970-01-01 00:01:00. | |
| struct tm tm_data{.tm_sec = 60, | |
| .tm_min = 0, | |
| .tm_hour = 0, | |
| .tm_mday = 1, | |
| .tm_mon = Month::JANUARY, | |
| .tm_year = tm_year(1970), | |
| .tm_wday = 0, | |
| .tm_yday = 0, | |
| .tm_isdst = 0}; | |
| EXPECT_THAT(LIBC_NAMESPACE::mktime(&tm_data), | |
| Succeeds(static_cast<time_t>(60))); | |
| EXPECT_TM_EQ((tm{.tm_sec = 0, | |
| .tm_min = 1, | |
| .tm_hour = 0, | |
| .tm_mday = 1, | |
| .tm_mon = Month::JANUARY, | |
| .tm_year = tm_year(1970), | |
| .tm_wday = 4, | |
| .tm_yday = 0, | |
| .tm_isdst = 0}), | |
| tm_data); | |
| } | |
| } | |
| TEST(LlvmLibcMkTime, InvalidMinutes) { | |
| { | |
| // -1 minute from 1970-01-01 00:00:00 returns 1969-12-31 23:59:00. | |
| struct tm tm_data{.tm_sec = 0, | |
| .tm_min = -1, | |
| .tm_hour = 0, | |
| .tm_mday = 1, | |
| .tm_mon = Month::JANUARY, | |
| .tm_year = tm_year(1970), | |
| .tm_wday = 0, | |
| .tm_yday = 0, | |
| .tm_isdst = 0}; | |
| EXPECT_THAT( | |
| LIBC_NAMESPACE::mktime(&tm_data), | |
| Succeeds<time_t>(-LIBC_NAMESPACE::time_constants::SECONDS_PER_MIN)); | |
| EXPECT_TM_EQ((tm{.tm_sec = 0, | |
| .tm_min = 59, | |
| .tm_hour = 23, | |
| .tm_mday = 31, | |
| .tm_mon = Month::DECEMBER, | |
| .tm_year = tm_year(1969), | |
| .tm_wday = 3, | |
| .tm_yday = 364, | |
| .tm_isdst = 0}), | |
| tm_data); | |
| } | |
| { | |
| // 60 minutes from 1970-01-01 00:00:00 returns 1970-01-01 01:00:00. | |
| struct tm tm_data{.tm_sec = 0, | |
| .tm_min = 60, | |
| .tm_hour = 0, | |
| .tm_mday = 1, | |
| .tm_mon = Month::JANUARY, | |
| .tm_year = tm_year(1970), | |
| .tm_wday = 0, | |
| .tm_yday = 0, | |
| .tm_isdst = 0}; | |
| EXPECT_THAT( | |
| LIBC_NAMESPACE::mktime(&tm_data), | |
| Succeeds<time_t>(60 * LIBC_NAMESPACE::time_constants::SECONDS_PER_MIN)); | |
| EXPECT_TM_EQ((tm{.tm_sec = 0, | |
| .tm_min = 0, | |
| .tm_hour = 1, | |
| .tm_mday = 1, | |
| .tm_mon = Month::JANUARY, | |
| .tm_year = tm_year(1970), | |
| .tm_wday = 4, | |
| .tm_yday = 0, | |
| .tm_isdst = 0}), | |
| tm_data); | |
| } | |
| } | |
| TEST(LlvmLibcMkTime, InvalidHours) { | |
| { | |
| // -1 hour from 1970-01-01 00:00:00 returns 1969-12-31 23:00:00. | |
| struct tm tm_data{.tm_sec = 0, | |
| .tm_min = 0, | |
| .tm_hour = -1, | |
| .tm_mday = 1, | |
| .tm_mon = Month::JANUARY, | |
| .tm_year = tm_year(1970), | |
| .tm_wday = 0, | |
| .tm_yday = 0, | |
| .tm_isdst = 0}; | |
| EXPECT_THAT( | |
| LIBC_NAMESPACE::mktime(&tm_data), | |
| Succeeds<time_t>(-LIBC_NAMESPACE::time_constants::SECONDS_PER_HOUR)); | |
| EXPECT_TM_EQ((tm{.tm_sec = 0, | |
| .tm_min = 0, | |
| .tm_hour = 23, | |
| .tm_mday = 31, | |
| .tm_mon = Month::DECEMBER, | |
| .tm_year = tm_year(1969), | |
| .tm_wday = 3, | |
| .tm_yday = 364, | |
| .tm_isdst = 0}), | |
| tm_data); | |
| } | |
| { | |
| // 24 hours from 1970-01-01 00:00:00 returns 1970-01-02 00:00:00. | |
| struct tm tm_data{.tm_sec = 0, | |
| .tm_min = 0, | |
| .tm_hour = 24, | |
| .tm_mday = 1, | |
| .tm_mon = Month::JANUARY, | |
| .tm_year = tm_year(1970), | |
| .tm_wday = 0, | |
| .tm_yday = 0, | |
| .tm_isdst = 0}; | |
| EXPECT_THAT(LIBC_NAMESPACE::mktime(&tm_data), | |
| Succeeds<time_t>( | |
| 24 * LIBC_NAMESPACE::time_constants::SECONDS_PER_HOUR)); | |
| EXPECT_TM_EQ((tm{.tm_sec = 0, | |
| .tm_min = 0, | |
| .tm_hour = 0, | |
| .tm_mday = 2, | |
| .tm_mon = Month::JANUARY, | |
| .tm_year = tm_year(1970), | |
| .tm_wday = 5, | |
| .tm_yday = 1, | |
| .tm_isdst = 0}), | |
| tm_data); | |
| } | |
| } | |
| TEST(LlvmLibcMkTime, InvalidYear) { | |
| // -1 year from 1970-01-01 00:00:00 returns 1969-01-01 00:00:00. | |
| struct tm tm_data{.tm_sec = 0, | |
| .tm_min = 0, | |
| .tm_hour = 0, | |
| .tm_mday = 1, | |
| .tm_mon = Month::JANUARY, | |
| .tm_year = tm_year(1969), | |
| .tm_wday = 0, | |
| .tm_yday = 0, | |
| .tm_isdst = 0}; | |
| EXPECT_THAT( | |
| LIBC_NAMESPACE::mktime(&tm_data), | |
| Succeeds<time_t>(-LIBC_NAMESPACE::time_constants::DAYS_PER_NON_LEAP_YEAR * | |
| LIBC_NAMESPACE::time_constants::SECONDS_PER_DAY)); | |
| EXPECT_TM_EQ((tm{.tm_sec = 0, | |
| .tm_min = 0, | |
| .tm_hour = 0, | |
| .tm_mday = 1, | |
| .tm_mon = Month::JANUARY, | |
| .tm_year = tm_year(1969), | |
| .tm_wday = 3, | |
| .tm_yday = 0, | |
| .tm_isdst = 0}), | |
| tm_data); | |
| } | |
| TEST(LlvmLibcMkTime, InvalidEndOf32BitEpochYear) { | |
| if (sizeof(time_t) != 4) | |
| return; | |
| { | |
| // 2038-01-19 03:14:08 tests overflow of the second in 2038. | |
| struct tm tm_data{.tm_sec = 8, | |
| .tm_min = 14, | |
| .tm_hour = 3, | |
| .tm_mday = 19, | |
| .tm_mon = Month::JANUARY, | |
| .tm_year = tm_year(2038), | |
| .tm_wday = 0, | |
| .tm_yday = 0, | |
| .tm_isdst = 0}; | |
| EXPECT_THAT(LIBC_NAMESPACE::mktime(&tm_data), Fails<time_t>(EOVERFLOW)); | |
| } | |
| { | |
| // 2038-01-19 03:15:07 tests overflow of the minute in 2038. | |
| struct tm tm_data{.tm_sec = 7, | |
| .tm_min = 15, | |
| .tm_hour = 3, | |
| .tm_mday = 19, | |
| .tm_mon = Month::JANUARY, | |
| .tm_year = tm_year(2038), | |
| .tm_wday = 0, | |
| .tm_yday = 0, | |
| .tm_isdst = 0}; | |
| EXPECT_THAT(LIBC_NAMESPACE::mktime(&tm_data), Fails<time_t>(EOVERFLOW)); | |
| } | |
| { | |
| // 2038-01-19 04:14:07 tests overflow of the hour in 2038. | |
| struct tm tm_data{.tm_sec = 7, | |
| .tm_min = 14, | |
| .tm_hour = 4, | |
| .tm_mday = 19, | |
| .tm_mon = Month::JANUARY, | |
| .tm_year = tm_year(2038), | |
| .tm_wday = 0, | |
| .tm_yday = 0, | |
| .tm_isdst = 0}; | |
| EXPECT_THAT(LIBC_NAMESPACE::mktime(&tm_data), Fails<time_t>(EOVERFLOW)); | |
| } | |
| { | |
| // 2038-01-20 03:14:07 tests overflow of the day in 2038. | |
| struct tm tm_data{.tm_sec = 7, | |
| .tm_min = 14, | |
| .tm_hour = 3, | |
| .tm_mday = 20, | |
| .tm_mon = Month::JANUARY, | |
| .tm_year = tm_year(2038), | |
| .tm_wday = 0, | |
| .tm_yday = 0, | |
| .tm_isdst = 0}; | |
| EXPECT_THAT(LIBC_NAMESPACE::mktime(&tm_data), Fails<time_t>(EOVERFLOW)); | |
| } | |
| { | |
| // 2038-02-19 03:14:07 tests overflow of the month in 2038. | |
| struct tm tm_data{.tm_sec = 7, | |
| .tm_min = 14, | |
| .tm_hour = 3, | |
| .tm_mday = 19, | |
| .tm_mon = Month::FEBRUARY, | |
| .tm_year = tm_year(2038), | |
| .tm_wday = 0, | |
| .tm_yday = 0, | |
| .tm_isdst = 0}; | |
| EXPECT_THAT(LIBC_NAMESPACE::mktime(&tm_data), Fails<time_t>(EOVERFLOW)); | |
| } | |
| { | |
| // 2039-01-19 03:14:07 tests overflow of the year. | |
| struct tm tm_data{.tm_sec = 7, | |
| .tm_min = 14, | |
| .tm_hour = 3, | |
| .tm_mday = 19, | |
| .tm_mon = Month::JANUARY, | |
| .tm_year = tm_year(2039), | |
| .tm_wday = 0, | |
| .tm_yday = 0, | |
| .tm_isdst = 0}; | |
| EXPECT_THAT(LIBC_NAMESPACE::mktime(&tm_data), Fails<time_t>(EOVERFLOW)); | |
| } | |
| } | |
| TEST(LlvmLibcMkTime, InvalidMonths) { | |
| { | |
| // -1 month from 1970-01-01 00:00:00 returns 1969-12-01 00:00:00. | |
| struct tm tm_data{.tm_sec = 0, | |
| .tm_min = 0, | |
| .tm_hour = 0, | |
| .tm_mday = 0, | |
| .tm_mon = -1, | |
| .tm_year = tm_year(1970), | |
| .tm_wday = 0, | |
| .tm_yday = 0, | |
| .tm_isdst = 0}; | |
| EXPECT_THAT(LIBC_NAMESPACE::mktime(&tm_data), | |
| Succeeds<time_t>( | |
| -32 * LIBC_NAMESPACE::time_constants::SECONDS_PER_DAY)); | |
| EXPECT_TM_EQ((tm{.tm_sec = 0, | |
| .tm_min = 0, | |
| .tm_hour = 0, | |
| .tm_mday = 30, | |
| .tm_mon = Month::NOVEMBER, | |
| .tm_year = tm_year(1969), | |
| .tm_wday = 0, | |
| .tm_yday = 333, | |
| .tm_isdst = 0}), | |
| tm_data); | |
| } | |
| { | |
| // 1970-13-01 00:00:00 returns 1971-01-01 00:00:00. | |
| struct tm tm_data{.tm_sec = 0, | |
| .tm_min = 0, | |
| .tm_hour = 0, | |
| .tm_mday = 1, | |
| .tm_mon = 12, | |
| .tm_year = tm_year(1970), | |
| .tm_wday = 0, | |
| .tm_yday = 0, | |
| .tm_isdst = 0}; | |
| EXPECT_THAT(LIBC_NAMESPACE::mktime(&tm_data), | |
| Succeeds<time_t>( | |
| LIBC_NAMESPACE::time_constants::DAYS_PER_NON_LEAP_YEAR * | |
| LIBC_NAMESPACE::time_constants::SECONDS_PER_DAY)); | |
| EXPECT_TM_EQ((tm{.tm_sec = 0, | |
| .tm_min = 0, | |
| .tm_hour = 0, | |
| .tm_mday = 1, | |
| .tm_mon = Month::JANUARY, | |
| .tm_year = tm_year(1971), | |
| .tm_wday = 5, | |
| .tm_yday = 0, | |
| .tm_isdst = 0}), | |
| tm_data); | |
| } | |
| } | |
| TEST(LlvmLibcMkTime, InvalidDays) { | |
| { | |
| // -1 day from 1970-01-01 00:00:00 returns 1969-12-31 00:00:00. | |
| struct tm tm_data{.tm_sec = 0, | |
| .tm_min = 0, | |
| .tm_hour = 0, | |
| .tm_mday = (1 - 1), | |
| .tm_mon = Month::JANUARY, | |
| .tm_year = tm_year(1970), | |
| .tm_wday = 0, | |
| .tm_yday = 0, | |
| .tm_isdst = 0}; | |
| EXPECT_THAT( | |
| LIBC_NAMESPACE::mktime(&tm_data), | |
| Succeeds<time_t>(-1 * LIBC_NAMESPACE::time_constants::SECONDS_PER_DAY)); | |
| EXPECT_TM_EQ((tm{.tm_sec = 0, | |
| .tm_min = 0, | |
| .tm_hour = 0, | |
| .tm_mday = 31, | |
| .tm_mon = Month::DECEMBER, | |
| .tm_year = tm_year(1969), | |
| .tm_wday = 3, | |
| .tm_yday = 364, | |
| .tm_isdst = 0}), | |
| tm_data); | |
| } | |
| { | |
| // 1970-01-32 00:00:00 returns 1970-02-01 00:00:00. | |
| struct tm tm_data{.tm_sec = 0, | |
| .tm_min = 0, | |
| .tm_hour = 0, | |
| .tm_mday = 32, | |
| .tm_mon = Month::JANUARY, | |
| .tm_year = tm_year(1970), | |
| .tm_wday = 0, | |
| .tm_yday = 0, | |
| .tm_isdst = 0}; | |
| EXPECT_THAT( | |
| LIBC_NAMESPACE::mktime(&tm_data), | |
| Succeeds<time_t>(31 * LIBC_NAMESPACE::time_constants::SECONDS_PER_DAY)); | |
| EXPECT_TM_EQ((tm{.tm_sec = 0, | |
| .tm_min = 0, | |
| .tm_hour = 0, | |
| .tm_mday = 1, | |
| .tm_mon = Month::FEBRUARY, | |
| .tm_year = tm_year(1970), | |
| .tm_wday = 0, | |
| .tm_yday = 31, | |
| .tm_isdst = 0}), | |
| tm_data); | |
| } | |
| { | |
| // 1970-02-29 00:00:00 returns 1970-03-01 00:00:00. | |
| struct tm tm_data{.tm_sec = 0, | |
| .tm_min = 0, | |
| .tm_hour = 0, | |
| .tm_mday = 29, | |
| .tm_mon = Month::FEBRUARY, | |
| .tm_year = tm_year(1970), | |
| .tm_wday = 0, | |
| .tm_yday = 0, | |
| .tm_isdst = 0}; | |
| EXPECT_THAT( | |
| LIBC_NAMESPACE::mktime(&tm_data), | |
| Succeeds<time_t>(59 * LIBC_NAMESPACE::time_constants::SECONDS_PER_DAY)); | |
| EXPECT_TM_EQ((tm{.tm_sec = 0, | |
| .tm_min = 0, | |
| .tm_hour = 0, | |
| .tm_mday = 1, | |
| .tm_mon = Month::MARCH, | |
| .tm_year = tm_year(1970), | |
| .tm_wday = 0, | |
| .tm_yday = 59, | |
| .tm_isdst = 0}), | |
| tm_data); | |
| } | |
| { | |
| // 1972-02-30 00:00:00 returns 1972-03-01 00:00:00. | |
| struct tm tm_data{.tm_sec = 0, | |
| .tm_min = 0, | |
| .tm_hour = 0, | |
| .tm_mday = 30, | |
| .tm_mon = Month::FEBRUARY, | |
| .tm_year = tm_year(1972), | |
| .tm_wday = 0, | |
| .tm_yday = 0, | |
| .tm_isdst = 0}; | |
| EXPECT_THAT( | |
| LIBC_NAMESPACE::mktime(&tm_data), | |
| Succeeds<time_t>( | |
| ((2 * LIBC_NAMESPACE::time_constants::DAYS_PER_NON_LEAP_YEAR) + | |
| 60) * | |
| LIBC_NAMESPACE::time_constants::SECONDS_PER_DAY)); | |
| EXPECT_TM_EQ((tm{.tm_sec = 0, | |
| .tm_min = 0, | |
| .tm_hour = 0, | |
| .tm_mday = 1, | |
| .tm_mon = Month::MARCH, | |
| .tm_year = tm_year(1972), | |
| .tm_wday = 3, | |
| .tm_yday = 60, | |
| .tm_isdst = 0}), | |
| tm_data); | |
| } | |
| } | |
| TEST(LlvmLibcMkTime, EndOf32BitEpochYear) { | |
| // Test for maximum value of a signed 32-bit integer. | |
| // Test implementation can encode time for Tue 19 January 2038 03:14:07 UTC. | |
| { | |
| struct tm tm_data{.tm_sec = 7, | |
| .tm_min = 14, | |
| .tm_hour = 3, | |
| .tm_mday = 19, | |
| .tm_mon = Month::JANUARY, | |
| .tm_year = tm_year(2038), | |
| .tm_wday = 0, | |
| .tm_yday = 0, | |
| .tm_isdst = 0}; | |
| EXPECT_THAT(LIBC_NAMESPACE::mktime(&tm_data), Succeeds<time_t>(0x7FFFFFFF)); | |
| EXPECT_TM_EQ((tm{.tm_sec = 7, | |
| .tm_min = 14, | |
| .tm_hour = 3, | |
| .tm_mday = 19, | |
| .tm_mon = Month::JANUARY, | |
| .tm_year = tm_year(2038), | |
| .tm_wday = 2, | |
| .tm_yday = 18, | |
| .tm_isdst = 0}), | |
| tm_data); | |
| } | |
| // Now test some times before that, to ensure they are not rejected. | |
| { | |
| // 2038-01-19 03:13:59 tests that even a large seconds field is | |
| // accepted if the minutes field is smaller. | |
| struct tm tm_data{.tm_sec = 59, | |
| .tm_min = 13, | |
| .tm_hour = 3, | |
| .tm_mday = 19, | |
| .tm_mon = Month::JANUARY, | |
| .tm_year = tm_year(2038), | |
| .tm_wday = 0, | |
| .tm_yday = 0, | |
| .tm_isdst = 0}; | |
| EXPECT_THAT(LIBC_NAMESPACE::mktime(&tm_data), | |
| Succeeds<time_t>(0x7FFFFFFF - 8)); | |
| EXPECT_TM_EQ((tm{.tm_sec = 59, | |
| .tm_min = 13, | |
| .tm_hour = 3, | |
| .tm_mday = 19, | |
| .tm_mon = Month::JANUARY, | |
| .tm_year = tm_year(2038), | |
| .tm_wday = 2, | |
| .tm_yday = 18, | |
| .tm_isdst = 0}), | |
| tm_data); | |
| } | |
| { | |
| // 2038-01-19 02:59:59 tests that large seconds and minutes are | |
| // accepted if the hours field is smaller. | |
| struct tm tm_data{.tm_sec = 59, | |
| .tm_min = 59, | |
| .tm_hour = 2, | |
| .tm_mday = 19, | |
| .tm_mon = Month::JANUARY, | |
| .tm_year = tm_year(2038), | |
| .tm_wday = 0, | |
| .tm_yday = 0, | |
| .tm_isdst = 0}; | |
| EXPECT_THAT( | |
| LIBC_NAMESPACE::mktime(&tm_data), | |
| Succeeds<time_t>(0x7FFFFFFF - 8 - | |
| 14 * LIBC_NAMESPACE::time_constants::SECONDS_PER_MIN)); | |
| EXPECT_TM_EQ((tm{.tm_sec = 59, | |
| .tm_min = 59, | |
| .tm_hour = 2, | |
| .tm_mday = 19, | |
| .tm_mon = Month::JANUARY, | |
| .tm_year = tm_year(2038), | |
| .tm_wday = 2, | |
| .tm_yday = 18, | |
| .tm_isdst = 0}), | |
| tm_data); | |
| } | |
| { | |
| // 2038-01-18 23:59:59 tests that large seconds, minutes and hours | |
| // are accepted if the days field is smaller. | |
| struct tm tm_data{.tm_sec = 59, | |
| .tm_min = 59, | |
| .tm_hour = 23, | |
| .tm_mday = 18, | |
| .tm_mon = Month::JANUARY, | |
| .tm_year = tm_year(2038), | |
| .tm_wday = 0, | |
| .tm_yday = 0, | |
| .tm_isdst = 0}; | |
| EXPECT_THAT( | |
| LIBC_NAMESPACE::mktime(&tm_data), | |
| Succeeds<time_t>(0x7FFFFFFF - 8 - | |
| 14 * LIBC_NAMESPACE::time_constants::SECONDS_PER_MIN - | |
| 3 * LIBC_NAMESPACE::time_constants::SECONDS_PER_HOUR)); | |
| EXPECT_TM_EQ((tm{.tm_sec = 59, | |
| .tm_min = 59, | |
| .tm_hour = 23, | |
| .tm_mday = 18, | |
| .tm_mon = Month::JANUARY, | |
| .tm_year = tm_year(2038), | |
| .tm_wday = 1, | |
| .tm_yday = 17, | |
| .tm_isdst = 0}), | |
| tm_data); | |
| } | |
| { | |
| // 2038-01-18 23:59:59 tests that the final second of 2037 is | |
| // accepted. | |
| struct tm tm_data{.tm_sec = 59, | |
| .tm_min = 59, | |
| .tm_hour = 23, | |
| .tm_mday = 31, | |
| .tm_mon = Month::DECEMBER, | |
| .tm_year = tm_year(2037), | |
| .tm_wday = 0, | |
| .tm_yday = 0, | |
| .tm_isdst = 0}; | |
| EXPECT_THAT( | |
| LIBC_NAMESPACE::mktime(&tm_data), | |
| Succeeds<time_t>(0x7FFFFFFF - 8 - | |
| 14 * LIBC_NAMESPACE::time_constants::SECONDS_PER_MIN - | |
| 3 * LIBC_NAMESPACE::time_constants::SECONDS_PER_HOUR - | |
| 18 * LIBC_NAMESPACE::time_constants::SECONDS_PER_DAY)); | |
| EXPECT_TM_EQ((tm{.tm_sec = 59, | |
| .tm_min = 59, | |
| .tm_hour = 23, | |
| .tm_mday = 31, | |
| .tm_mon = Month::DECEMBER, | |
| .tm_year = tm_year(2037), | |
| .tm_wday = 4, | |
| .tm_yday = 364, | |
| .tm_isdst = 0}), | |
| tm_data); | |
| } | |
| } | |
| TEST(LlvmLibcMkTime, Max64BitYear) { | |
| if (sizeof(time_t) == 4) | |
| return; | |
| { | |
| // Mon Jan 1 12:50:50 2170 (200 years from 1970), | |
| struct tm tm_data{.tm_sec = 50, | |
| .tm_min = 50, | |
| .tm_hour = 12, | |
| .tm_mday = 1, | |
| .tm_mon = Month::JANUARY, | |
| .tm_year = tm_year(2170), | |
| .tm_wday = 0, | |
| .tm_yday = 0, | |
| .tm_isdst = 0}; | |
| EXPECT_THAT(LIBC_NAMESPACE::mktime(&tm_data), Succeeds(6311479850)); | |
| EXPECT_TM_EQ((tm{.tm_sec = 50, | |
| .tm_min = 50, | |
| .tm_hour = 12, | |
| .tm_mday = 1, | |
| .tm_mon = Month::JANUARY, | |
| .tm_year = tm_year(2170), | |
| .tm_wday = 1, | |
| .tm_yday = 0, | |
| .tm_isdst = 0}), | |
| tm_data); | |
| } | |
| { | |
| // Test for Tue Jan 1 12:50:50 in 2,147,483,647th year. | |
| struct tm tm_data{.tm_sec = 50, | |
| .tm_min = 50, | |
| .tm_hour = 12, | |
| .tm_mday = 1, | |
| .tm_mon = Month::JANUARY, | |
| .tm_year = tm_year(2147483647), | |
| .tm_wday = 0, | |
| .tm_yday = 0, | |
| .tm_isdst = 0}; | |
| EXPECT_THAT(LIBC_NAMESPACE::mktime(&tm_data), Succeeds(67767976202043050)); | |
| EXPECT_TM_EQ((tm{.tm_sec = 50, | |
| .tm_min = 50, | |
| .tm_hour = 12, | |
| .tm_mday = 1, | |
| .tm_mon = Month::JANUARY, | |
| .tm_year = tm_year(2147483647), | |
| .tm_wday = 2, | |
| .tm_yday = 0, | |
| .tm_isdst = 0}), | |
| tm_data); | |
| } | |
| } |