1 //===-- Unittests for gmtime ----------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "src/time/gmtime.h" 10 #include "src/time/time_utils.h" 11 #include "test/ErrnoSetterMatcher.h" 12 #include "test/src/time/TmMatcher.h" 13 #include "utils/UnitTest/Test.h" 14 15 #include <errno.h> 16 #include <limits.h> 17 #include <string.h> 18 19 using __llvm_libc::testing::ErrnoSetterMatcher::Fails; 20 using __llvm_libc::testing::ErrnoSetterMatcher::Succeeds; 21 using __llvm_libc::time_utils::TimeConstants; 22 23 TEST(LlvmLibcGmTime, OutOfRange) { 24 time_t seconds = 25 1 + INT_MAX * static_cast<int64_t>( 26 TimeConstants::NUMBER_OF_SECONDS_IN_LEAP_YEAR); 27 struct tm *tm_data = __llvm_libc::gmtime(&seconds); 28 EXPECT_TRUE(tm_data == nullptr); 29 EXPECT_EQ(llvmlibc_errno, EOVERFLOW); 30 31 llvmlibc_errno = 0; 32 seconds = INT_MIN * static_cast<int64_t>( 33 TimeConstants::NUMBER_OF_SECONDS_IN_LEAP_YEAR) - 34 1; 35 tm_data = __llvm_libc::gmtime(&seconds); 36 EXPECT_TRUE(tm_data == nullptr); 37 EXPECT_EQ(llvmlibc_errno, EOVERFLOW); 38 } 39 40 TEST(LlvmLibcGmTime, InvalidSeconds) { 41 time_t seconds = 0; 42 struct tm *tm_data = nullptr; 43 // -1 second from 1970-01-01 00:00:00 returns 1969-12-31 23:59:59. 44 seconds = -1; 45 tm_data = __llvm_libc::gmtime(&seconds); 46 EXPECT_TM_EQ((tm{59, // sec 47 59, // min 48 23, // hr 49 31, // day 50 12 - 1, // tm_mon starts with 0 for Jan 51 1969 - TimeConstants::TIME_YEAR_BASE, // year 52 3, // wday 53 364, // yday 54 0}), 55 *tm_data); 56 // 60 seconds from 1970-01-01 00:00:00 returns 1970-01-01 00:01:00. 57 seconds = 60; 58 tm_data = __llvm_libc::gmtime(&seconds); 59 EXPECT_TM_EQ((tm{0, // sec 60 1, // min 61 0, // hr 62 1, // day 63 0, // tm_mon starts with 0 for Jan 64 1970 - TimeConstants::TIME_YEAR_BASE, // year 65 4, // wday 66 0, // yday 67 0}), 68 *tm_data); 69 } 70 71 TEST(LlvmLibcGmTime, InvalidMinutes) { 72 time_t seconds = 0; 73 struct tm *tm_data = nullptr; 74 // -1 minute from 1970-01-01 00:00:00 returns 1969-12-31 23:59:00. 75 seconds = -TimeConstants::SECONDS_PER_MIN; 76 tm_data = __llvm_libc::gmtime(&seconds); 77 EXPECT_TM_EQ((tm{0, // sec 78 59, // min 79 23, // hr 80 31, // day 81 11, // tm_mon starts with 0 for Jan 82 1969 - TimeConstants::TIME_YEAR_BASE, // year 83 3, // wday 84 0, // yday 85 0}), 86 *tm_data); 87 // 60 minutes from 1970-01-01 00:00:00 returns 1970-01-01 01:00:00. 88 seconds = 60 * TimeConstants::SECONDS_PER_MIN; 89 tm_data = __llvm_libc::gmtime(&seconds); 90 EXPECT_TM_EQ((tm{0, // sec 91 0, // min 92 1, // hr 93 1, // day 94 0, // tm_mon starts with 0 for Jan 95 1970 - TimeConstants::TIME_YEAR_BASE, // year 96 4, // wday 97 0, // yday 98 0}), 99 *tm_data); 100 } 101 102 TEST(LlvmLibcGmTime, InvalidHours) { 103 time_t seconds = 0; 104 struct tm *tm_data = nullptr; 105 // -1 hour from 1970-01-01 00:00:00 returns 1969-12-31 23:00:00. 106 seconds = -TimeConstants::SECONDS_PER_HOUR; 107 tm_data = __llvm_libc::gmtime(&seconds); 108 EXPECT_TM_EQ((tm{0, // sec 109 0, // min 110 23, // hr 111 31, // day 112 11, // tm_mon starts with 0 for Jan 113 1969 - TimeConstants::TIME_YEAR_BASE, // year 114 3, // wday 115 0, // yday 116 0}), 117 *tm_data); 118 // 24 hours from 1970-01-01 00:00:00 returns 1970-01-02 00:00:00. 119 seconds = 24 * TimeConstants::SECONDS_PER_HOUR; 120 tm_data = __llvm_libc::gmtime(&seconds); 121 EXPECT_TM_EQ((tm{0, // sec 122 0, // min 123 0, // hr 124 2, // day 125 0, // tm_mon starts with 0 for Jan 126 1970 - TimeConstants::TIME_YEAR_BASE, // year 127 5, // wday 128 0, // yday 129 0}), 130 *tm_data); 131 } 132 133 TEST(LlvmLibcGmTime, InvalidYear) { 134 // -1 year from 1970-01-01 00:00:00 returns 1969-01-01 00:00:00. 135 time_t seconds = 136 -TimeConstants::DAYS_PER_NON_LEAP_YEAR * TimeConstants::SECONDS_PER_DAY; 137 struct tm *tm_data = __llvm_libc::gmtime(&seconds); 138 EXPECT_TM_EQ((tm{0, // sec 139 0, // min 140 0, // hr 141 1, // day 142 0, // tm_mon starts with 0 for Jan 143 1969 - TimeConstants::TIME_YEAR_BASE, // year 144 3, // wday 145 0, // yday 146 0}), 147 *tm_data); 148 } 149 150 TEST(LlvmLibcGmTime, InvalidMonths) { 151 time_t seconds = 0; 152 struct tm *tm_data = nullptr; 153 // -1 month from 1970-01-01 00:00:00 returns 1969-12-01 00:00:00. 154 seconds = -31 * TimeConstants::SECONDS_PER_DAY; 155 tm_data = __llvm_libc::gmtime(&seconds); 156 EXPECT_TM_EQ((tm{0, // sec 157 0, // min 158 0, // hr 159 1, // day 160 12 - 1, // tm_mon starts with 0 for Jan 161 1969 - TimeConstants::TIME_YEAR_BASE, // year 162 1, // wday 163 0, // yday 164 0}), 165 *tm_data); 166 // 1970-13-01 00:00:00 returns 1971-01-01 00:00:00. 167 seconds = 168 TimeConstants::DAYS_PER_NON_LEAP_YEAR * TimeConstants::SECONDS_PER_DAY; 169 tm_data = __llvm_libc::gmtime(&seconds); 170 EXPECT_TM_EQ((tm{0, // sec 171 0, // min 172 0, // hr 173 1, // day 174 0, // tm_mon starts with 0 for Jan 175 1971 - TimeConstants::TIME_YEAR_BASE, // year 176 5, // wday 177 0, // yday 178 0}), 179 *tm_data); 180 } 181 182 TEST(LlvmLibcGmTime, InvalidDays) { 183 time_t seconds = 0; 184 struct tm *tm_data = nullptr; 185 // -1 day from 1970-01-01 00:00:00 returns 1969-12-31 00:00:00. 186 seconds = -1 * TimeConstants::SECONDS_PER_DAY; 187 tm_data = __llvm_libc::gmtime(&seconds); 188 EXPECT_TM_EQ((tm{0, // sec 189 0, // min 190 0, // hr 191 31, // day 192 11, // tm_mon starts with 0 for Jan 193 1969 - TimeConstants::TIME_YEAR_BASE, // year 194 3, // wday 195 0, // yday 196 0}), 197 *tm_data); 198 199 // 1970-01-32 00:00:00 returns 1970-02-01 00:00:00. 200 seconds = 31 * TimeConstants::SECONDS_PER_DAY; 201 tm_data = __llvm_libc::gmtime(&seconds); 202 EXPECT_TM_EQ((tm{0, // sec 203 0, // min 204 0, // hr 205 1, // day 206 0, // tm_mon starts with 0 for Jan 207 1970 - TimeConstants::TIME_YEAR_BASE, // year 208 0, // wday 209 0, // yday 210 0}), 211 *tm_data); 212 213 // 1970-02-29 00:00:00 returns 1970-03-01 00:00:00. 214 seconds = 59 * TimeConstants::SECONDS_PER_DAY; 215 tm_data = __llvm_libc::gmtime(&seconds); 216 EXPECT_TM_EQ((tm{0, // sec 217 0, // min 218 0, // hr 219 1, // day 220 2, // tm_mon starts with 0 for Jan 221 1970 - TimeConstants::TIME_YEAR_BASE, // year 222 0, // wday 223 0, // yday 224 0}), 225 *tm_data); 226 227 // 1972-02-30 00:00:00 returns 1972-03-01 00:00:00. 228 seconds = ((2 * TimeConstants::DAYS_PER_NON_LEAP_YEAR) + 60) * 229 TimeConstants::SECONDS_PER_DAY; 230 tm_data = __llvm_libc::gmtime(&seconds); 231 EXPECT_TM_EQ((tm{0, // sec 232 0, // min 233 0, // hr 234 1, // day 235 2, // tm_mon starts with 0 for Jan 236 1972 - TimeConstants::TIME_YEAR_BASE, // year 237 3, // wday 238 0, // yday 239 0}), 240 *tm_data); 241 } 242 243 TEST(LlvmLibcGmTime, EndOf32BitEpochYear) { 244 // Test for maximum value of a signed 32-bit integer. 245 // Test implementation can encode time for Tue 19 January 2038 03:14:07 UTC. 246 time_t seconds = 0x7FFFFFFF; 247 struct tm *tm_data = __llvm_libc::gmtime(&seconds); 248 EXPECT_TM_EQ((tm{7, // sec 249 14, // min 250 3, // hr 251 19, // day 252 0, // tm_mon starts with 0 for Jan 253 2038 - TimeConstants::TIME_YEAR_BASE, // year 254 2, // wday 255 7, // yday 256 0}), 257 *tm_data); 258 } 259 260 TEST(LlvmLibcGmTime, Max64BitYear) { 261 if (sizeof(time_t) == 4) 262 return; 263 // Mon Jan 1 12:50:50 2170 (200 years from 1970), 264 time_t seconds = 6311479850; 265 struct tm *tm_data = __llvm_libc::gmtime(&seconds); 266 EXPECT_TM_EQ((tm{50, // sec 267 50, // min 268 12, // hr 269 1, // day 270 0, // tm_mon starts with 0 for Jan 271 2170 - TimeConstants::TIME_YEAR_BASE, // year 272 1, // wday 273 50, // yday 274 0}), 275 *tm_data); 276 277 // Test for Tue Jan 1 12:50:50 in 2,147,483,647th year. 278 seconds = 67767976202043050; 279 tm_data = __llvm_libc::gmtime(&seconds); 280 EXPECT_TM_EQ((tm{50, // sec 281 50, // min 282 12, // hr 283 1, // day 284 0, // tm_mon starts with 0 for Jan 285 2147483647 - TimeConstants::TIME_YEAR_BASE, // year 286 2, // wday 287 50, // yday 288 0}), 289 *tm_data); 290 } 291