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