16f0f844eSRaman Tenneti //===-- Unittests for mktime ----------------------------------------------===// 26f0f844eSRaman Tenneti // 36f0f844eSRaman Tenneti // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 46f0f844eSRaman Tenneti // See https://llvm.org/LICENSE.txt for license information. 56f0f844eSRaman Tenneti // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 66f0f844eSRaman Tenneti // 76f0f844eSRaman Tenneti //===----------------------------------------------------------------------===// 86f0f844eSRaman Tenneti 972ce6294Slntue #include "src/__support/CPP/limits.h" // INT_MAX 106f0f844eSRaman Tenneti #include "src/time/mktime.h" 11*f9c2377fSMichael Jones #include "src/time/time_constants.h" 124f1fe19dSSiva Chandra Reddy #include "test/UnitTest/ErrnoSetterMatcher.h" 13af1315c2SSiva Chandra Reddy #include "test/UnitTest/Test.h" 14a72499e4SRaman Tenneti #include "test/src/time/TmHelper.h" 15034f5629SRaman Tenneti #include "test/src/time/TmMatcher.h" 166f0f844eSRaman Tenneti 17b6bc9d72SGuillaume Chatelet using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails; 18b6bc9d72SGuillaume Chatelet using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds; 19*f9c2377fSMichael Jones using LIBC_NAMESPACE::time_constants::Month; 206f0f844eSRaman Tenneti 219ad0ac8eSJeff Bailey static inline constexpr int tm_year(int year) { 22*f9c2377fSMichael Jones return year - LIBC_NAMESPACE::time_constants::TIME_YEAR_BASE; 236f0f844eSRaman Tenneti } 246f0f844eSRaman Tenneti 251df0dbfcSMichael Jones TEST(LlvmLibcMkTime, FailureSetsErrno) { 26*f9c2377fSMichael Jones struct tm tm_data{.tm_sec = INT_MAX, 27*f9c2377fSMichael Jones .tm_min = INT_MAX, 28*f9c2377fSMichael Jones .tm_hour = INT_MAX, 29*f9c2377fSMichael Jones .tm_mday = INT_MAX, 30*f9c2377fSMichael Jones .tm_mon = INT_MAX - 1, 31*f9c2377fSMichael Jones .tm_year = tm_year(INT_MAX), 32*f9c2377fSMichael Jones .tm_wday = 0, 33*f9c2377fSMichael Jones .tm_yday = 0, 34*f9c2377fSMichael Jones .tm_isdst = 0}; 35b6bc9d72SGuillaume Chatelet EXPECT_THAT(LIBC_NAMESPACE::mktime(&tm_data), Fails(EOVERFLOW)); 366f0f844eSRaman Tenneti } 376f0f844eSRaman Tenneti 38eaae52c1SRaman Tenneti TEST(LlvmLibcMkTime, InvalidSeconds) { 399ad0ac8eSJeff Bailey { 40034f5629SRaman Tenneti // -1 second from 1970-01-01 00:00:00 returns 1969-12-31 23:59:59. 41*f9c2377fSMichael Jones struct tm tm_data{.tm_sec = -1, 42*f9c2377fSMichael Jones .tm_min = 0, 43*f9c2377fSMichael Jones .tm_hour = 0, 44*f9c2377fSMichael Jones .tm_mday = 1, 45*f9c2377fSMichael Jones .tm_mon = Month::JANUARY, 46*f9c2377fSMichael Jones .tm_year = tm_year(1970), 47*f9c2377fSMichael Jones .tm_wday = 0, 48*f9c2377fSMichael Jones .tm_yday = 0, 49*f9c2377fSMichael Jones .tm_isdst = 0}; 50b6bc9d72SGuillaume Chatelet EXPECT_THAT(LIBC_NAMESPACE::mktime(&tm_data), Succeeds(-1)); 519ad0ac8eSJeff Bailey EXPECT_TM_EQ((tm{.tm_sec = 59, 529ad0ac8eSJeff Bailey .tm_min = 59, 539ad0ac8eSJeff Bailey .tm_hour = 23, 549ad0ac8eSJeff Bailey .tm_mday = 31, 559ad0ac8eSJeff Bailey .tm_mon = Month::DECEMBER, 569ad0ac8eSJeff Bailey .tm_year = tm_year(1969), 579ad0ac8eSJeff Bailey .tm_wday = 3, 58824b1677SMikhail R. Gadelha .tm_yday = 364, 59824b1677SMikhail R. Gadelha .tm_isdst = 0}), 60034f5629SRaman Tenneti tm_data); 619ad0ac8eSJeff Bailey } 629ad0ac8eSJeff Bailey 639ad0ac8eSJeff Bailey { 64034f5629SRaman Tenneti // 60 seconds from 1970-01-01 00:00:00 returns 1970-01-01 00:01:00. 65*f9c2377fSMichael Jones struct tm tm_data{.tm_sec = 60, 66*f9c2377fSMichael Jones .tm_min = 0, 67*f9c2377fSMichael Jones .tm_hour = 0, 68*f9c2377fSMichael Jones .tm_mday = 1, 69*f9c2377fSMichael Jones .tm_mon = Month::JANUARY, 70*f9c2377fSMichael Jones .tm_year = tm_year(1970), 71*f9c2377fSMichael Jones .tm_wday = 0, 72*f9c2377fSMichael Jones .tm_yday = 0, 73*f9c2377fSMichael Jones .tm_isdst = 0}; 74b6bc9d72SGuillaume Chatelet EXPECT_THAT(LIBC_NAMESPACE::mktime(&tm_data), Succeeds(60)); 759ad0ac8eSJeff Bailey EXPECT_TM_EQ((tm{.tm_sec = 0, 769ad0ac8eSJeff Bailey .tm_min = 1, 779ad0ac8eSJeff Bailey .tm_hour = 0, 789ad0ac8eSJeff Bailey .tm_mday = 1, 799ad0ac8eSJeff Bailey .tm_mon = Month::JANUARY, 809ad0ac8eSJeff Bailey .tm_year = tm_year(1970), 819ad0ac8eSJeff Bailey .tm_wday = 4, 82824b1677SMikhail R. Gadelha .tm_yday = 0, 83824b1677SMikhail R. Gadelha .tm_isdst = 0}), 84034f5629SRaman Tenneti tm_data); 856f0f844eSRaman Tenneti } 869ad0ac8eSJeff Bailey } 876f0f844eSRaman Tenneti 88eaae52c1SRaman Tenneti TEST(LlvmLibcMkTime, InvalidMinutes) { 899ad0ac8eSJeff Bailey { 90034f5629SRaman Tenneti // -1 minute from 1970-01-01 00:00:00 returns 1969-12-31 23:59:00. 91*f9c2377fSMichael Jones struct tm tm_data{.tm_sec = 0, 92*f9c2377fSMichael Jones .tm_min = -1, 93*f9c2377fSMichael Jones .tm_hour = 0, 94*f9c2377fSMichael Jones .tm_mday = 1, 95*f9c2377fSMichael Jones .tm_mon = Month::JANUARY, 96*f9c2377fSMichael Jones .tm_year = tm_year(1970), 97*f9c2377fSMichael Jones .tm_wday = 0, 98*f9c2377fSMichael Jones .tm_yday = 0, 99*f9c2377fSMichael Jones .tm_isdst = 0}; 100b6bc9d72SGuillaume Chatelet EXPECT_THAT(LIBC_NAMESPACE::mktime(&tm_data), 101*f9c2377fSMichael Jones Succeeds(-LIBC_NAMESPACE::time_constants::SECONDS_PER_MIN)); 1029ad0ac8eSJeff Bailey EXPECT_TM_EQ((tm{.tm_sec = 0, 1039ad0ac8eSJeff Bailey .tm_min = 59, 1049ad0ac8eSJeff Bailey .tm_hour = 23, 1059ad0ac8eSJeff Bailey .tm_mday = 31, 1069ad0ac8eSJeff Bailey .tm_mon = Month::DECEMBER, 1079ad0ac8eSJeff Bailey .tm_year = tm_year(1969), 1089ad0ac8eSJeff Bailey .tm_wday = 3, 109824b1677SMikhail R. Gadelha .tm_yday = 0, 110824b1677SMikhail R. Gadelha .tm_isdst = 0}), 111034f5629SRaman Tenneti tm_data); 1129ad0ac8eSJeff Bailey } 1139ad0ac8eSJeff Bailey 1149ad0ac8eSJeff Bailey { 115034f5629SRaman Tenneti // 60 minutes from 1970-01-01 00:00:00 returns 1970-01-01 01:00:00. 116*f9c2377fSMichael Jones struct tm tm_data{.tm_sec = 0, 117*f9c2377fSMichael Jones .tm_min = 60, 118*f9c2377fSMichael Jones .tm_hour = 0, 119*f9c2377fSMichael Jones .tm_mday = 1, 120*f9c2377fSMichael Jones .tm_mon = Month::JANUARY, 121*f9c2377fSMichael Jones .tm_year = tm_year(1970), 122*f9c2377fSMichael Jones .tm_wday = 0, 123*f9c2377fSMichael Jones .tm_yday = 0, 124*f9c2377fSMichael Jones .tm_isdst = 0}; 125b6bc9d72SGuillaume Chatelet EXPECT_THAT(LIBC_NAMESPACE::mktime(&tm_data), 126*f9c2377fSMichael Jones Succeeds(60 * LIBC_NAMESPACE::time_constants::SECONDS_PER_MIN)); 1279ad0ac8eSJeff Bailey EXPECT_TM_EQ((tm{.tm_sec = 0, 1289ad0ac8eSJeff Bailey .tm_min = 0, 1299ad0ac8eSJeff Bailey .tm_hour = 1, 1309ad0ac8eSJeff Bailey .tm_mday = 1, 1319ad0ac8eSJeff Bailey .tm_mon = Month::JANUARY, 1329ad0ac8eSJeff Bailey .tm_year = tm_year(1970), 1339ad0ac8eSJeff Bailey .tm_wday = 4, 134824b1677SMikhail R. Gadelha .tm_yday = 0, 135824b1677SMikhail R. Gadelha .tm_isdst = 0}), 136034f5629SRaman Tenneti tm_data); 1376f0f844eSRaman Tenneti } 1389ad0ac8eSJeff Bailey } 1396f0f844eSRaman Tenneti 140eaae52c1SRaman Tenneti TEST(LlvmLibcMkTime, InvalidHours) { 1419ad0ac8eSJeff Bailey { 142034f5629SRaman Tenneti // -1 hour from 1970-01-01 00:00:00 returns 1969-12-31 23:00:00. 143*f9c2377fSMichael Jones struct tm tm_data{.tm_sec = 0, 144*f9c2377fSMichael Jones .tm_min = 0, 145*f9c2377fSMichael Jones .tm_hour = -1, 146*f9c2377fSMichael Jones .tm_mday = 1, 147*f9c2377fSMichael Jones .tm_mon = Month::JANUARY, 148*f9c2377fSMichael Jones .tm_year = tm_year(1970), 149*f9c2377fSMichael Jones .tm_wday = 0, 150*f9c2377fSMichael Jones .tm_yday = 0, 151*f9c2377fSMichael Jones .tm_isdst = 0}; 152b6bc9d72SGuillaume Chatelet EXPECT_THAT(LIBC_NAMESPACE::mktime(&tm_data), 153*f9c2377fSMichael Jones Succeeds(-LIBC_NAMESPACE::time_constants::SECONDS_PER_HOUR)); 1549ad0ac8eSJeff Bailey EXPECT_TM_EQ((tm{.tm_sec = 0, 1559ad0ac8eSJeff Bailey .tm_min = 0, 1569ad0ac8eSJeff Bailey .tm_hour = 23, 1579ad0ac8eSJeff Bailey .tm_mday = 31, 1589ad0ac8eSJeff Bailey .tm_mon = Month::DECEMBER, 1599ad0ac8eSJeff Bailey .tm_year = tm_year(1969), 1609ad0ac8eSJeff Bailey .tm_wday = 3, 161824b1677SMikhail R. Gadelha .tm_yday = 0, 162824b1677SMikhail R. Gadelha .tm_isdst = 0}), 163034f5629SRaman Tenneti tm_data); 1646f0f844eSRaman Tenneti } 1656f0f844eSRaman Tenneti 1669ad0ac8eSJeff Bailey { 1679ad0ac8eSJeff Bailey // 24 hours from 1970-01-01 00:00:00 returns 1970-01-02 00:00:00. 168*f9c2377fSMichael Jones struct tm tm_data{.tm_sec = 0, 169*f9c2377fSMichael Jones .tm_min = 0, 170*f9c2377fSMichael Jones .tm_hour = 24, 171*f9c2377fSMichael Jones .tm_mday = 1, 172*f9c2377fSMichael Jones .tm_mon = Month::JANUARY, 173*f9c2377fSMichael Jones .tm_year = tm_year(1970), 174*f9c2377fSMichael Jones .tm_wday = 0, 175*f9c2377fSMichael Jones .tm_yday = 0, 176*f9c2377fSMichael Jones .tm_isdst = 0}; 177*f9c2377fSMichael Jones EXPECT_THAT( 178*f9c2377fSMichael Jones LIBC_NAMESPACE::mktime(&tm_data), 179*f9c2377fSMichael Jones Succeeds(24 * LIBC_NAMESPACE::time_constants::SECONDS_PER_HOUR)); 1809ad0ac8eSJeff Bailey EXPECT_TM_EQ((tm{.tm_sec = 0, 1819ad0ac8eSJeff Bailey .tm_min = 0, 1829ad0ac8eSJeff Bailey .tm_hour = 0, 1839ad0ac8eSJeff Bailey .tm_mday = 2, 1849ad0ac8eSJeff Bailey .tm_mon = Month::JANUARY, 1859ad0ac8eSJeff Bailey .tm_year = tm_year(1970), 1869ad0ac8eSJeff Bailey .tm_wday = 5, 187824b1677SMikhail R. Gadelha .tm_yday = 0, 188824b1677SMikhail R. Gadelha .tm_isdst = 0}), 1899ad0ac8eSJeff Bailey tm_data); 1909ad0ac8eSJeff Bailey } 1919ad0ac8eSJeff Bailey } 1929ad0ac8eSJeff Bailey 193eaae52c1SRaman Tenneti TEST(LlvmLibcMkTime, InvalidYear) { 194034f5629SRaman Tenneti // -1 year from 1970-01-01 00:00:00 returns 1969-01-01 00:00:00. 195*f9c2377fSMichael Jones struct tm tm_data{.tm_sec = 0, 196*f9c2377fSMichael Jones .tm_min = 0, 197*f9c2377fSMichael Jones .tm_hour = 0, 198*f9c2377fSMichael Jones .tm_mday = 1, 199*f9c2377fSMichael Jones .tm_mon = Month::JANUARY, 200*f9c2377fSMichael Jones .tm_year = tm_year(1969), 201*f9c2377fSMichael Jones .tm_wday = 0, 202*f9c2377fSMichael Jones .tm_yday = 0, 203*f9c2377fSMichael Jones .tm_isdst = 0}; 204b6bc9d72SGuillaume Chatelet EXPECT_THAT(LIBC_NAMESPACE::mktime(&tm_data), 205*f9c2377fSMichael Jones Succeeds(-LIBC_NAMESPACE::time_constants::DAYS_PER_NON_LEAP_YEAR * 206*f9c2377fSMichael Jones LIBC_NAMESPACE::time_constants::SECONDS_PER_DAY)); 2079ad0ac8eSJeff Bailey EXPECT_TM_EQ((tm{.tm_sec = 0, 2089ad0ac8eSJeff Bailey .tm_min = 0, 2099ad0ac8eSJeff Bailey .tm_hour = 0, 2109ad0ac8eSJeff Bailey .tm_mday = 1, 2119ad0ac8eSJeff Bailey .tm_mon = Month::JANUARY, 2129ad0ac8eSJeff Bailey .tm_year = tm_year(1969), 2139ad0ac8eSJeff Bailey .tm_wday = 3, 214824b1677SMikhail R. Gadelha .tm_yday = 0, 215824b1677SMikhail R. Gadelha .tm_isdst = 0}), 216034f5629SRaman Tenneti tm_data); 2176f0f844eSRaman Tenneti } 2186f0f844eSRaman Tenneti 219eaae52c1SRaman Tenneti TEST(LlvmLibcMkTime, InvalidEndOf32BitEpochYear) { 2209e344545SMikhail R. Gadelha if (sizeof(time_t) != 4) 2216f0f844eSRaman Tenneti return; 2229ad0ac8eSJeff Bailey { 2236f0f844eSRaman Tenneti // 2038-01-19 03:14:08 tests overflow of the second in 2038. 224*f9c2377fSMichael Jones struct tm tm_data{.tm_sec = 8, 225*f9c2377fSMichael Jones .tm_min = 14, 226*f9c2377fSMichael Jones .tm_hour = 3, 227*f9c2377fSMichael Jones .tm_mday = 19, 228*f9c2377fSMichael Jones .tm_mon = Month::JANUARY, 229*f9c2377fSMichael Jones .tm_year = tm_year(2038), 230*f9c2377fSMichael Jones .tm_wday = 0, 231*f9c2377fSMichael Jones .tm_yday = 0, 232*f9c2377fSMichael Jones .tm_isdst = 0}; 233b6bc9d72SGuillaume Chatelet EXPECT_THAT(LIBC_NAMESPACE::mktime(&tm_data), Fails(EOVERFLOW)); 2349ad0ac8eSJeff Bailey } 2359ad0ac8eSJeff Bailey 2369ad0ac8eSJeff Bailey { 2376f0f844eSRaman Tenneti // 2038-01-19 03:15:07 tests overflow of the minute in 2038. 238*f9c2377fSMichael Jones struct tm tm_data{.tm_sec = 7, 239*f9c2377fSMichael Jones .tm_min = 15, 240*f9c2377fSMichael Jones .tm_hour = 3, 241*f9c2377fSMichael Jones .tm_mday = 19, 242*f9c2377fSMichael Jones .tm_mon = Month::JANUARY, 243*f9c2377fSMichael Jones .tm_year = tm_year(2038), 244*f9c2377fSMichael Jones .tm_wday = 0, 245*f9c2377fSMichael Jones .tm_yday = 0, 246*f9c2377fSMichael Jones .tm_isdst = 0}; 247b6bc9d72SGuillaume Chatelet EXPECT_THAT(LIBC_NAMESPACE::mktime(&tm_data), Fails(EOVERFLOW)); 2489ad0ac8eSJeff Bailey } 2499ad0ac8eSJeff Bailey 2509ad0ac8eSJeff Bailey { 2516f0f844eSRaman Tenneti // 2038-01-19 04:14:07 tests overflow of the hour in 2038. 252*f9c2377fSMichael Jones struct tm tm_data{.tm_sec = 7, 253*f9c2377fSMichael Jones .tm_min = 14, 254*f9c2377fSMichael Jones .tm_hour = 4, 255*f9c2377fSMichael Jones .tm_mday = 19, 256*f9c2377fSMichael Jones .tm_mon = Month::JANUARY, 257*f9c2377fSMichael Jones .tm_year = tm_year(2038), 258*f9c2377fSMichael Jones .tm_wday = 0, 259*f9c2377fSMichael Jones .tm_yday = 0, 260*f9c2377fSMichael Jones .tm_isdst = 0}; 261b6bc9d72SGuillaume Chatelet EXPECT_THAT(LIBC_NAMESPACE::mktime(&tm_data), Fails(EOVERFLOW)); 2629ad0ac8eSJeff Bailey } 2639ad0ac8eSJeff Bailey 2649ad0ac8eSJeff Bailey { 2656f0f844eSRaman Tenneti // 2038-01-20 03:14:07 tests overflow of the day in 2038. 266*f9c2377fSMichael Jones struct tm tm_data{.tm_sec = 7, 267*f9c2377fSMichael Jones .tm_min = 14, 268*f9c2377fSMichael Jones .tm_hour = 3, 269*f9c2377fSMichael Jones .tm_mday = 20, 270*f9c2377fSMichael Jones .tm_mon = Month::JANUARY, 271*f9c2377fSMichael Jones .tm_year = tm_year(2038), 272*f9c2377fSMichael Jones .tm_wday = 0, 273*f9c2377fSMichael Jones .tm_yday = 0, 274*f9c2377fSMichael Jones .tm_isdst = 0}; 275b6bc9d72SGuillaume Chatelet EXPECT_THAT(LIBC_NAMESPACE::mktime(&tm_data), Fails(EOVERFLOW)); 2769ad0ac8eSJeff Bailey } 2779ad0ac8eSJeff Bailey 2789ad0ac8eSJeff Bailey { 2796f0f844eSRaman Tenneti // 2038-02-19 03:14:07 tests overflow of the month in 2038. 280*f9c2377fSMichael Jones struct tm tm_data{.tm_sec = 7, 281*f9c2377fSMichael Jones .tm_min = 14, 282*f9c2377fSMichael Jones .tm_hour = 3, 283*f9c2377fSMichael Jones .tm_mday = 19, 284*f9c2377fSMichael Jones .tm_mon = Month::FEBRUARY, 285*f9c2377fSMichael Jones .tm_year = tm_year(2038), 286*f9c2377fSMichael Jones .tm_wday = 0, 287*f9c2377fSMichael Jones .tm_yday = 0, 288*f9c2377fSMichael Jones .tm_isdst = 0}; 289b6bc9d72SGuillaume Chatelet EXPECT_THAT(LIBC_NAMESPACE::mktime(&tm_data), Fails(EOVERFLOW)); 2909ad0ac8eSJeff Bailey } 2919ad0ac8eSJeff Bailey 2929ad0ac8eSJeff Bailey { 2936f0f844eSRaman Tenneti // 2039-01-19 03:14:07 tests overflow of the year. 294*f9c2377fSMichael Jones struct tm tm_data{.tm_sec = 7, 295*f9c2377fSMichael Jones .tm_min = 14, 296*f9c2377fSMichael Jones .tm_hour = 3, 297*f9c2377fSMichael Jones .tm_mday = 19, 298*f9c2377fSMichael Jones .tm_mon = Month::JANUARY, 299*f9c2377fSMichael Jones .tm_year = tm_year(2039), 300*f9c2377fSMichael Jones .tm_wday = 0, 301*f9c2377fSMichael Jones .tm_yday = 0, 302*f9c2377fSMichael Jones .tm_isdst = 0}; 303b6bc9d72SGuillaume Chatelet EXPECT_THAT(LIBC_NAMESPACE::mktime(&tm_data), Fails(EOVERFLOW)); 3046f0f844eSRaman Tenneti } 3059ad0ac8eSJeff Bailey } 3066f0f844eSRaman Tenneti 307eaae52c1SRaman Tenneti TEST(LlvmLibcMkTime, InvalidMonths) { 3089ad0ac8eSJeff Bailey { 309034f5629SRaman Tenneti // -1 month from 1970-01-01 00:00:00 returns 1969-12-01 00:00:00. 310*f9c2377fSMichael Jones struct tm tm_data{.tm_sec = 0, 311*f9c2377fSMichael Jones .tm_min = 0, 312*f9c2377fSMichael Jones .tm_hour = 0, 313*f9c2377fSMichael Jones .tm_mday = 0, 314*f9c2377fSMichael Jones .tm_mon = -1, 315*f9c2377fSMichael Jones .tm_year = tm_year(1970), 316*f9c2377fSMichael Jones .tm_wday = 0, 317*f9c2377fSMichael Jones .tm_yday = 0, 318*f9c2377fSMichael Jones .tm_isdst = 0}; 319*f9c2377fSMichael Jones EXPECT_THAT( 320*f9c2377fSMichael Jones LIBC_NAMESPACE::mktime(&tm_data), 321*f9c2377fSMichael Jones Succeeds(-32 * LIBC_NAMESPACE::time_constants::SECONDS_PER_DAY)); 3229ad0ac8eSJeff Bailey EXPECT_TM_EQ((tm{.tm_sec = 0, 3239ad0ac8eSJeff Bailey .tm_min = 0, 3249ad0ac8eSJeff Bailey .tm_hour = 0, 3259ad0ac8eSJeff Bailey .tm_mday = 1, 3269ad0ac8eSJeff Bailey .tm_mon = Month::DECEMBER, 3279ad0ac8eSJeff Bailey .tm_year = tm_year(1969), 3289ad0ac8eSJeff Bailey .tm_wday = 1, 329824b1677SMikhail R. Gadelha .tm_yday = 0, 330824b1677SMikhail R. Gadelha .tm_isdst = 0}), 331034f5629SRaman Tenneti tm_data); 3329ad0ac8eSJeff Bailey } 3339ad0ac8eSJeff Bailey 3349ad0ac8eSJeff Bailey { 335034f5629SRaman Tenneti // 1970-13-01 00:00:00 returns 1971-01-01 00:00:00. 336*f9c2377fSMichael Jones struct tm tm_data{.tm_sec = 0, 337*f9c2377fSMichael Jones .tm_min = 0, 338*f9c2377fSMichael Jones .tm_hour = 0, 339*f9c2377fSMichael Jones .tm_mday = 1, 340*f9c2377fSMichael Jones .tm_mon = 12, 341*f9c2377fSMichael Jones .tm_year = tm_year(1970), 342*f9c2377fSMichael Jones .tm_wday = 0, 343*f9c2377fSMichael Jones .tm_yday = 0, 344*f9c2377fSMichael Jones .tm_isdst = 0}; 345*f9c2377fSMichael Jones EXPECT_THAT( 346*f9c2377fSMichael Jones LIBC_NAMESPACE::mktime(&tm_data), 347*f9c2377fSMichael Jones Succeeds(LIBC_NAMESPACE::time_constants::DAYS_PER_NON_LEAP_YEAR * 348*f9c2377fSMichael Jones LIBC_NAMESPACE::time_constants::SECONDS_PER_DAY)); 3499ad0ac8eSJeff Bailey EXPECT_TM_EQ((tm{.tm_sec = 0, 3509ad0ac8eSJeff Bailey .tm_min = 0, 3519ad0ac8eSJeff Bailey .tm_hour = 0, 3529ad0ac8eSJeff Bailey .tm_mday = 1, 3539ad0ac8eSJeff Bailey .tm_mon = Month::JANUARY, 3549ad0ac8eSJeff Bailey .tm_year = tm_year(1971), 3559ad0ac8eSJeff Bailey .tm_wday = 5, 356824b1677SMikhail R. Gadelha .tm_yday = 0, 357824b1677SMikhail R. Gadelha .tm_isdst = 0}), 358034f5629SRaman Tenneti tm_data); 3596f0f844eSRaman Tenneti } 3609ad0ac8eSJeff Bailey } 3616f0f844eSRaman Tenneti 362eaae52c1SRaman Tenneti TEST(LlvmLibcMkTime, InvalidDays) { 3639ad0ac8eSJeff Bailey { 364034f5629SRaman Tenneti // -1 day from 1970-01-01 00:00:00 returns 1969-12-31 00:00:00. 365*f9c2377fSMichael Jones struct tm tm_data{.tm_sec = 0, 366*f9c2377fSMichael Jones .tm_min = 0, 367*f9c2377fSMichael Jones .tm_hour = 0, 368*f9c2377fSMichael Jones .tm_mday = (1 - 1), 369*f9c2377fSMichael Jones .tm_mon = Month::JANUARY, 370*f9c2377fSMichael Jones .tm_year = tm_year(1970), 371*f9c2377fSMichael Jones .tm_wday = 0, 372*f9c2377fSMichael Jones .tm_yday = 0, 373*f9c2377fSMichael Jones .tm_isdst = 0}; 374b6bc9d72SGuillaume Chatelet EXPECT_THAT(LIBC_NAMESPACE::mktime(&tm_data), 375*f9c2377fSMichael Jones Succeeds(-1 * LIBC_NAMESPACE::time_constants::SECONDS_PER_DAY)); 3769ad0ac8eSJeff Bailey EXPECT_TM_EQ((tm{.tm_sec = 0, 3779ad0ac8eSJeff Bailey .tm_min = 0, 3789ad0ac8eSJeff Bailey .tm_hour = 0, 3799ad0ac8eSJeff Bailey .tm_mday = 31, 3809ad0ac8eSJeff Bailey .tm_mon = Month::DECEMBER, 3819ad0ac8eSJeff Bailey .tm_year = tm_year(1969), 3829ad0ac8eSJeff Bailey .tm_wday = 3, 383824b1677SMikhail R. Gadelha .tm_yday = 0, 384824b1677SMikhail R. Gadelha .tm_isdst = 0}), 385034f5629SRaman Tenneti tm_data); 3866f0f844eSRaman Tenneti } 3876f0f844eSRaman Tenneti 3889ad0ac8eSJeff Bailey { 3899ad0ac8eSJeff Bailey // 1970-01-32 00:00:00 returns 1970-02-01 00:00:00. 390*f9c2377fSMichael Jones struct tm tm_data{.tm_sec = 0, 391*f9c2377fSMichael Jones .tm_min = 0, 392*f9c2377fSMichael Jones .tm_hour = 0, 393*f9c2377fSMichael Jones .tm_mday = 32, 394*f9c2377fSMichael Jones .tm_mon = Month::JANUARY, 395*f9c2377fSMichael Jones .tm_year = tm_year(1970), 396*f9c2377fSMichael Jones .tm_wday = 0, 397*f9c2377fSMichael Jones .tm_yday = 0, 398*f9c2377fSMichael Jones .tm_isdst = 0}; 399b6bc9d72SGuillaume Chatelet EXPECT_THAT(LIBC_NAMESPACE::mktime(&tm_data), 400*f9c2377fSMichael Jones Succeeds(31 * LIBC_NAMESPACE::time_constants::SECONDS_PER_DAY)); 4019ad0ac8eSJeff Bailey EXPECT_TM_EQ((tm{.tm_sec = 0, 4029ad0ac8eSJeff Bailey .tm_min = 0, 4039ad0ac8eSJeff Bailey .tm_hour = 0, 4049ad0ac8eSJeff Bailey .tm_mday = 1, 4059ad0ac8eSJeff Bailey .tm_mon = Month::FEBRUARY, 4069ad0ac8eSJeff Bailey .tm_year = tm_year(1970), 4079ad0ac8eSJeff Bailey .tm_wday = 0, 408824b1677SMikhail R. Gadelha .tm_yday = 0, 409824b1677SMikhail R. Gadelha .tm_isdst = 0}), 4109ad0ac8eSJeff Bailey tm_data); 4119ad0ac8eSJeff Bailey } 4129ad0ac8eSJeff Bailey 4139ad0ac8eSJeff Bailey { 4149ad0ac8eSJeff Bailey // 1970-02-29 00:00:00 returns 1970-03-01 00:00:00. 415*f9c2377fSMichael Jones struct tm tm_data{.tm_sec = 0, 416*f9c2377fSMichael Jones .tm_min = 0, 417*f9c2377fSMichael Jones .tm_hour = 0, 418*f9c2377fSMichael Jones .tm_mday = 29, 419*f9c2377fSMichael Jones .tm_mon = Month::FEBRUARY, 420*f9c2377fSMichael Jones .tm_year = tm_year(1970), 421*f9c2377fSMichael Jones .tm_wday = 0, 422*f9c2377fSMichael Jones .tm_yday = 0, 423*f9c2377fSMichael Jones .tm_isdst = 0}; 424b6bc9d72SGuillaume Chatelet EXPECT_THAT(LIBC_NAMESPACE::mktime(&tm_data), 425*f9c2377fSMichael Jones Succeeds(59 * LIBC_NAMESPACE::time_constants::SECONDS_PER_DAY)); 4269ad0ac8eSJeff Bailey EXPECT_TM_EQ((tm{.tm_sec = 0, 4279ad0ac8eSJeff Bailey .tm_min = 0, 4289ad0ac8eSJeff Bailey .tm_hour = 0, 4299ad0ac8eSJeff Bailey .tm_mday = 1, 4309ad0ac8eSJeff Bailey .tm_mon = Month::MARCH, 4319ad0ac8eSJeff Bailey .tm_year = tm_year(1970), 4329ad0ac8eSJeff Bailey .tm_wday = 0, 433824b1677SMikhail R. Gadelha .tm_yday = 0, 434824b1677SMikhail R. Gadelha .tm_isdst = 0}), 4359ad0ac8eSJeff Bailey tm_data); 4369ad0ac8eSJeff Bailey } 4379ad0ac8eSJeff Bailey 4389ad0ac8eSJeff Bailey { 4399ad0ac8eSJeff Bailey // 1972-02-30 00:00:00 returns 1972-03-01 00:00:00. 440*f9c2377fSMichael Jones struct tm tm_data{.tm_sec = 0, 441*f9c2377fSMichael Jones .tm_min = 0, 442*f9c2377fSMichael Jones .tm_hour = 0, 443*f9c2377fSMichael Jones .tm_mday = 30, 444*f9c2377fSMichael Jones .tm_mon = Month::FEBRUARY, 445*f9c2377fSMichael Jones .tm_year = tm_year(1972), 446*f9c2377fSMichael Jones .tm_wday = 0, 447*f9c2377fSMichael Jones .tm_yday = 0, 448*f9c2377fSMichael Jones .tm_isdst = 0}; 449*f9c2377fSMichael Jones EXPECT_THAT( 450*f9c2377fSMichael Jones LIBC_NAMESPACE::mktime(&tm_data), 451*f9c2377fSMichael Jones Succeeds(((2 * LIBC_NAMESPACE::time_constants::DAYS_PER_NON_LEAP_YEAR) + 452*f9c2377fSMichael Jones 60) * 453*f9c2377fSMichael Jones LIBC_NAMESPACE::time_constants::SECONDS_PER_DAY)); 4549ad0ac8eSJeff Bailey EXPECT_TM_EQ((tm{.tm_sec = 0, 4559ad0ac8eSJeff Bailey .tm_min = 0, 4569ad0ac8eSJeff Bailey .tm_hour = 0, 4579ad0ac8eSJeff Bailey .tm_mday = 1, 4589ad0ac8eSJeff Bailey .tm_mon = Month::MARCH, 4599ad0ac8eSJeff Bailey .tm_year = tm_year(1972), 4609ad0ac8eSJeff Bailey .tm_wday = 3, 461824b1677SMikhail R. Gadelha .tm_yday = 0, 462824b1677SMikhail R. Gadelha .tm_isdst = 0}), 4639ad0ac8eSJeff Bailey tm_data); 4649ad0ac8eSJeff Bailey } 4659ad0ac8eSJeff Bailey } 4669ad0ac8eSJeff Bailey 467eaae52c1SRaman Tenneti TEST(LlvmLibcMkTime, EndOf32BitEpochYear) { 4686f0f844eSRaman Tenneti // Test for maximum value of a signed 32-bit integer. 4696f0f844eSRaman Tenneti // Test implementation can encode time for Tue 19 January 2038 03:14:07 UTC. 47081d82739SSimon Tatham { 471*f9c2377fSMichael Jones struct tm tm_data{.tm_sec = 7, 472*f9c2377fSMichael Jones .tm_min = 14, 473*f9c2377fSMichael Jones .tm_hour = 3, 474*f9c2377fSMichael Jones .tm_mday = 19, 475*f9c2377fSMichael Jones .tm_mon = Month::JANUARY, 476*f9c2377fSMichael Jones .tm_year = tm_year(2038), 477*f9c2377fSMichael Jones .tm_wday = 0, 478*f9c2377fSMichael Jones .tm_yday = 0, 479*f9c2377fSMichael Jones .tm_isdst = 0}; 480b6bc9d72SGuillaume Chatelet EXPECT_THAT(LIBC_NAMESPACE::mktime(&tm_data), Succeeds(0x7FFFFFFF)); 4819ad0ac8eSJeff Bailey EXPECT_TM_EQ((tm{.tm_sec = 7, 4829ad0ac8eSJeff Bailey .tm_min = 14, 4839ad0ac8eSJeff Bailey .tm_hour = 3, 4849ad0ac8eSJeff Bailey .tm_mday = 19, 4859ad0ac8eSJeff Bailey .tm_mon = Month::JANUARY, 4869ad0ac8eSJeff Bailey .tm_year = tm_year(2038), 4879ad0ac8eSJeff Bailey .tm_wday = 2, 488824b1677SMikhail R. Gadelha .tm_yday = 7, 489824b1677SMikhail R. Gadelha .tm_isdst = 0}), 490034f5629SRaman Tenneti tm_data); 4916f0f844eSRaman Tenneti } 4926f0f844eSRaman Tenneti 49381d82739SSimon Tatham // Now test some times before that, to ensure they are not rejected. 49481d82739SSimon Tatham { 49581d82739SSimon Tatham // 2038-01-19 03:13:59 tests that even a large seconds field is 49681d82739SSimon Tatham // accepted if the minutes field is smaller. 497*f9c2377fSMichael Jones struct tm tm_data{.tm_sec = 59, 498*f9c2377fSMichael Jones .tm_min = 13, 499*f9c2377fSMichael Jones .tm_hour = 3, 500*f9c2377fSMichael Jones .tm_mday = 19, 501*f9c2377fSMichael Jones .tm_mon = Month::JANUARY, 502*f9c2377fSMichael Jones .tm_year = tm_year(2038), 503*f9c2377fSMichael Jones .tm_wday = 0, 504*f9c2377fSMichael Jones .tm_yday = 0, 505*f9c2377fSMichael Jones .tm_isdst = 0}; 50681d82739SSimon Tatham EXPECT_THAT(LIBC_NAMESPACE::mktime(&tm_data), Succeeds(0x7FFFFFFF - 8)); 50781d82739SSimon Tatham EXPECT_TM_EQ((tm{.tm_sec = 59, 50881d82739SSimon Tatham .tm_min = 13, 50981d82739SSimon Tatham .tm_hour = 3, 51081d82739SSimon Tatham .tm_mday = 19, 51181d82739SSimon Tatham .tm_mon = Month::JANUARY, 51281d82739SSimon Tatham .tm_year = tm_year(2038), 51381d82739SSimon Tatham .tm_wday = 2, 51481d82739SSimon Tatham .tm_yday = 7, 51581d82739SSimon Tatham .tm_isdst = 0}), 51681d82739SSimon Tatham tm_data); 51781d82739SSimon Tatham } 51881d82739SSimon Tatham 51981d82739SSimon Tatham { 52081d82739SSimon Tatham // 2038-01-19 02:59:59 tests that large seconds and minutes are 52181d82739SSimon Tatham // accepted if the hours field is smaller. 522*f9c2377fSMichael Jones struct tm tm_data{.tm_sec = 59, 523*f9c2377fSMichael Jones .tm_min = 59, 524*f9c2377fSMichael Jones .tm_hour = 2, 525*f9c2377fSMichael Jones .tm_mday = 19, 526*f9c2377fSMichael Jones .tm_mon = Month::JANUARY, 527*f9c2377fSMichael Jones .tm_year = tm_year(2038), 528*f9c2377fSMichael Jones .tm_wday = 0, 529*f9c2377fSMichael Jones .tm_yday = 0, 530*f9c2377fSMichael Jones .tm_isdst = 0}; 53181d82739SSimon Tatham EXPECT_THAT(LIBC_NAMESPACE::mktime(&tm_data), 532*f9c2377fSMichael Jones Succeeds(0x7FFFFFFF - 8 - 533*f9c2377fSMichael Jones 14 * LIBC_NAMESPACE::time_constants::SECONDS_PER_MIN)); 53481d82739SSimon Tatham EXPECT_TM_EQ((tm{.tm_sec = 59, 53581d82739SSimon Tatham .tm_min = 59, 53681d82739SSimon Tatham .tm_hour = 2, 53781d82739SSimon Tatham .tm_mday = 19, 53881d82739SSimon Tatham .tm_mon = Month::JANUARY, 53981d82739SSimon Tatham .tm_year = tm_year(2038), 54081d82739SSimon Tatham .tm_wday = 2, 54181d82739SSimon Tatham .tm_yday = 7, 54281d82739SSimon Tatham .tm_isdst = 0}), 54381d82739SSimon Tatham tm_data); 54481d82739SSimon Tatham } 54581d82739SSimon Tatham 54681d82739SSimon Tatham { 54781d82739SSimon Tatham // 2038-01-18 23:59:59 tests that large seconds, minutes and hours 54881d82739SSimon Tatham // are accepted if the days field is smaller. 549*f9c2377fSMichael Jones struct tm tm_data{.tm_sec = 59, 550*f9c2377fSMichael Jones .tm_min = 59, 551*f9c2377fSMichael Jones .tm_hour = 23, 552*f9c2377fSMichael Jones .tm_mday = 18, 553*f9c2377fSMichael Jones .tm_mon = Month::JANUARY, 554*f9c2377fSMichael Jones .tm_year = tm_year(2038), 555*f9c2377fSMichael Jones .tm_wday = 0, 556*f9c2377fSMichael Jones .tm_yday = 0, 557*f9c2377fSMichael Jones .tm_isdst = 0}; 55881d82739SSimon Tatham EXPECT_THAT(LIBC_NAMESPACE::mktime(&tm_data), 559*f9c2377fSMichael Jones Succeeds(0x7FFFFFFF - 8 - 560*f9c2377fSMichael Jones 14 * LIBC_NAMESPACE::time_constants::SECONDS_PER_MIN - 561*f9c2377fSMichael Jones 3 * LIBC_NAMESPACE::time_constants::SECONDS_PER_HOUR)); 56281d82739SSimon Tatham EXPECT_TM_EQ((tm{.tm_sec = 59, 56381d82739SSimon Tatham .tm_min = 59, 56481d82739SSimon Tatham .tm_hour = 23, 56581d82739SSimon Tatham .tm_mday = 18, 56681d82739SSimon Tatham .tm_mon = Month::JANUARY, 56781d82739SSimon Tatham .tm_year = tm_year(2038), 56881d82739SSimon Tatham .tm_wday = 2, 56981d82739SSimon Tatham .tm_yday = 7, 57081d82739SSimon Tatham .tm_isdst = 0}), 57181d82739SSimon Tatham tm_data); 57281d82739SSimon Tatham } 57381d82739SSimon Tatham 57481d82739SSimon Tatham { 57581d82739SSimon Tatham // 2038-01-18 23:59:59 tests that the final second of 2037 is 57681d82739SSimon Tatham // accepted. 577*f9c2377fSMichael Jones struct tm tm_data{.tm_sec = 59, 578*f9c2377fSMichael Jones .tm_min = 59, 579*f9c2377fSMichael Jones .tm_hour = 23, 580*f9c2377fSMichael Jones .tm_mday = 31, 581*f9c2377fSMichael Jones .tm_mon = Month::DECEMBER, 582*f9c2377fSMichael Jones .tm_year = tm_year(2037), 583*f9c2377fSMichael Jones .tm_wday = 0, 584*f9c2377fSMichael Jones .tm_yday = 0, 585*f9c2377fSMichael Jones .tm_isdst = 0}; 58681d82739SSimon Tatham EXPECT_THAT(LIBC_NAMESPACE::mktime(&tm_data), 587*f9c2377fSMichael Jones Succeeds(0x7FFFFFFF - 8 - 588*f9c2377fSMichael Jones 14 * LIBC_NAMESPACE::time_constants::SECONDS_PER_MIN - 589*f9c2377fSMichael Jones 3 * LIBC_NAMESPACE::time_constants::SECONDS_PER_HOUR - 590*f9c2377fSMichael Jones 18 * LIBC_NAMESPACE::time_constants::SECONDS_PER_DAY)); 59181d82739SSimon Tatham EXPECT_TM_EQ((tm{.tm_sec = 59, 59281d82739SSimon Tatham .tm_min = 59, 59381d82739SSimon Tatham .tm_hour = 23, 59481d82739SSimon Tatham .tm_mday = 31, 59581d82739SSimon Tatham .tm_mon = Month::DECEMBER, 59681d82739SSimon Tatham .tm_year = tm_year(2037), 59781d82739SSimon Tatham .tm_wday = 2, 59881d82739SSimon Tatham .tm_yday = 7, 59981d82739SSimon Tatham .tm_isdst = 0}), 60081d82739SSimon Tatham tm_data); 60181d82739SSimon Tatham } 60281d82739SSimon Tatham } 60381d82739SSimon Tatham 604eaae52c1SRaman Tenneti TEST(LlvmLibcMkTime, Max64BitYear) { 6056f0f844eSRaman Tenneti if (sizeof(time_t) == 4) 6066f0f844eSRaman Tenneti return; 6079ad0ac8eSJeff Bailey { 608034f5629SRaman Tenneti // Mon Jan 1 12:50:50 2170 (200 years from 1970), 609*f9c2377fSMichael Jones struct tm tm_data{.tm_sec = 50, 610*f9c2377fSMichael Jones .tm_min = 50, 611*f9c2377fSMichael Jones .tm_hour = 12, 612*f9c2377fSMichael Jones .tm_mday = 1, 613*f9c2377fSMichael Jones .tm_mon = Month::JANUARY, 614*f9c2377fSMichael Jones .tm_year = tm_year(2170), 615*f9c2377fSMichael Jones .tm_wday = 0, 616*f9c2377fSMichael Jones .tm_yday = 0, 617*f9c2377fSMichael Jones .tm_isdst = 0}; 618b6bc9d72SGuillaume Chatelet EXPECT_THAT(LIBC_NAMESPACE::mktime(&tm_data), Succeeds(6311479850)); 6199ad0ac8eSJeff Bailey EXPECT_TM_EQ((tm{.tm_sec = 50, 6209ad0ac8eSJeff Bailey .tm_min = 50, 6219ad0ac8eSJeff Bailey .tm_hour = 12, 6229ad0ac8eSJeff Bailey .tm_mday = 1, 6239ad0ac8eSJeff Bailey .tm_mon = Month::JANUARY, 6249ad0ac8eSJeff Bailey .tm_year = tm_year(2170), 6259ad0ac8eSJeff Bailey .tm_wday = 1, 626824b1677SMikhail R. Gadelha .tm_yday = 50, 627824b1677SMikhail R. Gadelha .tm_isdst = 0}), 628034f5629SRaman Tenneti tm_data); 6299ad0ac8eSJeff Bailey } 6306f0f844eSRaman Tenneti 6319ad0ac8eSJeff Bailey { 6326f0f844eSRaman Tenneti // Test for Tue Jan 1 12:50:50 in 2,147,483,647th year. 633*f9c2377fSMichael Jones struct tm tm_data{.tm_sec = 50, 634*f9c2377fSMichael Jones .tm_min = 50, 635*f9c2377fSMichael Jones .tm_hour = 12, 636*f9c2377fSMichael Jones .tm_mday = 1, 637*f9c2377fSMichael Jones .tm_mon = Month::JANUARY, 638*f9c2377fSMichael Jones .tm_year = tm_year(2147483647), 639*f9c2377fSMichael Jones .tm_wday = 0, 640*f9c2377fSMichael Jones .tm_yday = 0, 641*f9c2377fSMichael Jones .tm_isdst = 0}; 642b6bc9d72SGuillaume Chatelet EXPECT_THAT(LIBC_NAMESPACE::mktime(&tm_data), Succeeds(67767976202043050)); 6439ad0ac8eSJeff Bailey EXPECT_TM_EQ((tm{.tm_sec = 50, 6449ad0ac8eSJeff Bailey .tm_min = 50, 6459ad0ac8eSJeff Bailey .tm_hour = 12, 6469ad0ac8eSJeff Bailey .tm_mday = 1, 6479ad0ac8eSJeff Bailey .tm_mon = Month::JANUARY, 6489ad0ac8eSJeff Bailey .tm_year = tm_year(2147483647), 6499ad0ac8eSJeff Bailey .tm_wday = 2, 650824b1677SMikhail R. Gadelha .tm_yday = 50, 651824b1677SMikhail R. Gadelha .tm_isdst = 0}), 652034f5629SRaman Tenneti tm_data); 6536f0f844eSRaman Tenneti } 6549ad0ac8eSJeff Bailey } 655