1 //===-- Unittests for mktime ----------------------------------------------===// 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/__support/CPP/limits.h" // INT_MAX 10 #include "src/time/mktime.h" 11 #include "src/time/time_utils.h" 12 #include "test/UnitTest/ErrnoSetterMatcher.h" 13 #include "test/UnitTest/Test.h" 14 #include "test/src/time/TmHelper.h" 15 #include "test/src/time/TmMatcher.h" 16 17 using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails; 18 using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds; 19 using LIBC_NAMESPACE::time_utils::Month; 20 21 static inline constexpr int tm_year(int year) { 22 return year - TimeConstants::TIME_YEAR_BASE; 23 } 24 25 TEST(LlvmLibcMkTime, FailureSetsErrno) { 26 struct tm tm_data { 27 .tm_sec = INT_MAX, .tm_min = INT_MAX, .tm_hour = INT_MAX, 28 .tm_mday = INT_MAX, .tm_mon = INT_MAX - 1, .tm_year = tm_year(INT_MAX), 29 .tm_wday = 0, .tm_yday = 0, .tm_isdst = 0 30 }; 31 EXPECT_THAT(LIBC_NAMESPACE::mktime(&tm_data), Fails(EOVERFLOW)); 32 } 33 34 TEST(LlvmLibcMkTime, InvalidSeconds) { 35 { 36 // -1 second from 1970-01-01 00:00:00 returns 1969-12-31 23:59:59. 37 struct tm tm_data { 38 .tm_sec = -1, .tm_min = 0, .tm_hour = 0, .tm_mday = 1, 39 .tm_mon = Month::JANUARY, .tm_year = tm_year(1970), .tm_wday = 0, 40 .tm_yday = 0, .tm_isdst = 0 41 }; 42 EXPECT_THAT(LIBC_NAMESPACE::mktime(&tm_data), Succeeds(-1)); 43 EXPECT_TM_EQ((tm{.tm_sec = 59, 44 .tm_min = 59, 45 .tm_hour = 23, 46 .tm_mday = 31, 47 .tm_mon = Month::DECEMBER, 48 .tm_year = tm_year(1969), 49 .tm_wday = 3, 50 .tm_yday = 364, 51 .tm_isdst = 0}), 52 tm_data); 53 } 54 55 { 56 // 60 seconds from 1970-01-01 00:00:00 returns 1970-01-01 00:01:00. 57 struct tm tm_data { 58 .tm_sec = 60, .tm_min = 0, .tm_hour = 0, .tm_mday = 1, 59 .tm_mon = Month::JANUARY, .tm_year = tm_year(1970), .tm_wday = 0, 60 .tm_yday = 0, .tm_isdst = 0 61 }; 62 EXPECT_THAT(LIBC_NAMESPACE::mktime(&tm_data), Succeeds(60)); 63 EXPECT_TM_EQ((tm{.tm_sec = 0, 64 .tm_min = 1, 65 .tm_hour = 0, 66 .tm_mday = 1, 67 .tm_mon = Month::JANUARY, 68 .tm_year = tm_year(1970), 69 .tm_wday = 4, 70 .tm_yday = 0, 71 .tm_isdst = 0}), 72 tm_data); 73 } 74 } 75 76 TEST(LlvmLibcMkTime, InvalidMinutes) { 77 { 78 // -1 minute from 1970-01-01 00:00:00 returns 1969-12-31 23:59:00. 79 struct tm tm_data { 80 .tm_sec = 0, .tm_min = -1, .tm_hour = 0, .tm_mday = 1, 81 .tm_mon = Month::JANUARY, .tm_year = tm_year(1970), .tm_wday = 0, 82 .tm_yday = 0, .tm_isdst = 0 83 }; 84 EXPECT_THAT(LIBC_NAMESPACE::mktime(&tm_data), 85 Succeeds(-TimeConstants::SECONDS_PER_MIN)); 86 EXPECT_TM_EQ((tm{.tm_sec = 0, 87 .tm_min = 59, 88 .tm_hour = 23, 89 .tm_mday = 31, 90 .tm_mon = Month::DECEMBER, 91 .tm_year = tm_year(1969), 92 .tm_wday = 3, 93 .tm_yday = 0, 94 .tm_isdst = 0}), 95 tm_data); 96 } 97 98 { 99 // 60 minutes from 1970-01-01 00:00:00 returns 1970-01-01 01:00:00. 100 struct tm tm_data { 101 .tm_sec = 0, .tm_min = 60, .tm_hour = 0, .tm_mday = 1, 102 .tm_mon = Month::JANUARY, .tm_year = tm_year(1970), .tm_wday = 0, 103 .tm_yday = 0, .tm_isdst = 0 104 }; 105 EXPECT_THAT(LIBC_NAMESPACE::mktime(&tm_data), 106 Succeeds(60 * TimeConstants::SECONDS_PER_MIN)); 107 EXPECT_TM_EQ((tm{.tm_sec = 0, 108 .tm_min = 0, 109 .tm_hour = 1, 110 .tm_mday = 1, 111 .tm_mon = Month::JANUARY, 112 .tm_year = tm_year(1970), 113 .tm_wday = 4, 114 .tm_yday = 0, 115 .tm_isdst = 0}), 116 tm_data); 117 } 118 } 119 120 TEST(LlvmLibcMkTime, InvalidHours) { 121 { 122 // -1 hour from 1970-01-01 00:00:00 returns 1969-12-31 23:00:00. 123 struct tm tm_data { 124 .tm_sec = 0, .tm_min = 0, .tm_hour = -1, .tm_mday = 1, 125 .tm_mon = Month::JANUARY, .tm_year = tm_year(1970), .tm_wday = 0, 126 .tm_yday = 0, .tm_isdst = 0 127 }; 128 EXPECT_THAT(LIBC_NAMESPACE::mktime(&tm_data), 129 Succeeds(-TimeConstants::SECONDS_PER_HOUR)); 130 EXPECT_TM_EQ((tm{.tm_sec = 0, 131 .tm_min = 0, 132 .tm_hour = 23, 133 .tm_mday = 31, 134 .tm_mon = Month::DECEMBER, 135 .tm_year = tm_year(1969), 136 .tm_wday = 3, 137 .tm_yday = 0, 138 .tm_isdst = 0}), 139 tm_data); 140 } 141 142 { 143 // 24 hours from 1970-01-01 00:00:00 returns 1970-01-02 00:00:00. 144 struct tm tm_data { 145 .tm_sec = 0, .tm_min = 0, .tm_hour = 24, .tm_mday = 1, 146 .tm_mon = Month::JANUARY, .tm_year = tm_year(1970), .tm_wday = 0, 147 .tm_yday = 0, .tm_isdst = 0 148 }; 149 EXPECT_THAT(LIBC_NAMESPACE::mktime(&tm_data), 150 Succeeds(24 * TimeConstants::SECONDS_PER_HOUR)); 151 EXPECT_TM_EQ((tm{.tm_sec = 0, 152 .tm_min = 0, 153 .tm_hour = 0, 154 .tm_mday = 2, 155 .tm_mon = Month::JANUARY, 156 .tm_year = tm_year(1970), 157 .tm_wday = 5, 158 .tm_yday = 0, 159 .tm_isdst = 0}), 160 tm_data); 161 } 162 } 163 164 TEST(LlvmLibcMkTime, InvalidYear) { 165 // -1 year from 1970-01-01 00:00:00 returns 1969-01-01 00:00:00. 166 struct tm tm_data { 167 .tm_sec = 0, .tm_min = 0, .tm_hour = 0, .tm_mday = 1, 168 .tm_mon = Month::JANUARY, .tm_year = tm_year(1969), .tm_wday = 0, 169 .tm_yday = 0, .tm_isdst = 0 170 }; 171 EXPECT_THAT(LIBC_NAMESPACE::mktime(&tm_data), 172 Succeeds(-TimeConstants::DAYS_PER_NON_LEAP_YEAR * 173 TimeConstants::SECONDS_PER_DAY)); 174 EXPECT_TM_EQ((tm{.tm_sec = 0, 175 .tm_min = 0, 176 .tm_hour = 0, 177 .tm_mday = 1, 178 .tm_mon = Month::JANUARY, 179 .tm_year = tm_year(1969), 180 .tm_wday = 3, 181 .tm_yday = 0, 182 .tm_isdst = 0}), 183 tm_data); 184 } 185 186 TEST(LlvmLibcMkTime, InvalidEndOf32BitEpochYear) { 187 if (sizeof(time_t) != 4) 188 return; 189 { 190 // 2038-01-19 03:14:08 tests overflow of the second in 2038. 191 struct tm tm_data { 192 .tm_sec = 8, .tm_min = 14, .tm_hour = 3, .tm_mday = 19, 193 .tm_mon = Month::JANUARY, .tm_year = tm_year(2038), .tm_wday = 0, 194 .tm_yday = 0, .tm_isdst = 0 195 }; 196 EXPECT_THAT(LIBC_NAMESPACE::mktime(&tm_data), Fails(EOVERFLOW)); 197 } 198 199 { 200 // 2038-01-19 03:15:07 tests overflow of the minute in 2038. 201 struct tm tm_data { 202 .tm_sec = 7, .tm_min = 15, .tm_hour = 3, .tm_mday = 19, 203 .tm_mon = Month::JANUARY, .tm_year = tm_year(2038), .tm_wday = 0, 204 .tm_yday = 0, .tm_isdst = 0 205 }; 206 EXPECT_THAT(LIBC_NAMESPACE::mktime(&tm_data), Fails(EOVERFLOW)); 207 } 208 209 { 210 // 2038-01-19 04:14:07 tests overflow of the hour in 2038. 211 struct tm tm_data { 212 .tm_sec = 7, .tm_min = 14, .tm_hour = 4, .tm_mday = 19, 213 .tm_mon = Month::JANUARY, .tm_year = tm_year(2038), .tm_wday = 0, 214 .tm_yday = 0, .tm_isdst = 0 215 }; 216 EXPECT_THAT(LIBC_NAMESPACE::mktime(&tm_data), Fails(EOVERFLOW)); 217 } 218 219 { 220 // 2038-01-20 03:14:07 tests overflow of the day in 2038. 221 struct tm tm_data { 222 .tm_sec = 7, .tm_min = 14, .tm_hour = 3, .tm_mday = 20, 223 .tm_mon = Month::JANUARY, .tm_year = tm_year(2038), .tm_wday = 0, 224 .tm_yday = 0, .tm_isdst = 0 225 }; 226 EXPECT_THAT(LIBC_NAMESPACE::mktime(&tm_data), Fails(EOVERFLOW)); 227 } 228 229 { 230 // 2038-02-19 03:14:07 tests overflow of the month in 2038. 231 struct tm tm_data { 232 .tm_sec = 7, .tm_min = 14, .tm_hour = 3, .tm_mday = 19, 233 .tm_mon = Month::FEBRUARY, .tm_year = tm_year(2038), .tm_wday = 0, 234 .tm_yday = 0, .tm_isdst = 0 235 }; 236 EXPECT_THAT(LIBC_NAMESPACE::mktime(&tm_data), Fails(EOVERFLOW)); 237 } 238 239 { 240 // 2039-01-19 03:14:07 tests overflow of the year. 241 struct tm tm_data { 242 .tm_sec = 7, .tm_min = 14, .tm_hour = 3, .tm_mday = 19, 243 .tm_mon = Month::JANUARY, .tm_year = tm_year(2039), .tm_wday = 0, 244 .tm_yday = 0, .tm_isdst = 0 245 }; 246 EXPECT_THAT(LIBC_NAMESPACE::mktime(&tm_data), Fails(EOVERFLOW)); 247 } 248 } 249 250 TEST(LlvmLibcMkTime, InvalidMonths) { 251 { 252 // -1 month from 1970-01-01 00:00:00 returns 1969-12-01 00:00:00. 253 struct tm tm_data { 254 .tm_sec = 0, .tm_min = 0, .tm_hour = 0, .tm_mday = 0, .tm_mon = -1, 255 .tm_year = tm_year(1970), .tm_wday = 0, .tm_yday = 0, .tm_isdst = 0 256 }; 257 EXPECT_THAT(LIBC_NAMESPACE::mktime(&tm_data), 258 Succeeds(-32 * TimeConstants::SECONDS_PER_DAY)); 259 EXPECT_TM_EQ((tm{.tm_sec = 0, 260 .tm_min = 0, 261 .tm_hour = 0, 262 .tm_mday = 1, 263 .tm_mon = Month::DECEMBER, 264 .tm_year = tm_year(1969), 265 .tm_wday = 1, 266 .tm_yday = 0, 267 .tm_isdst = 0}), 268 tm_data); 269 } 270 271 { 272 // 1970-13-01 00:00:00 returns 1971-01-01 00:00:00. 273 struct tm tm_data { 274 .tm_sec = 0, .tm_min = 0, .tm_hour = 0, .tm_mday = 1, .tm_mon = 12, 275 .tm_year = tm_year(1970), .tm_wday = 0, .tm_yday = 0, .tm_isdst = 0 276 }; 277 EXPECT_THAT(LIBC_NAMESPACE::mktime(&tm_data), 278 Succeeds(TimeConstants::DAYS_PER_NON_LEAP_YEAR * 279 TimeConstants::SECONDS_PER_DAY)); 280 EXPECT_TM_EQ((tm{.tm_sec = 0, 281 .tm_min = 0, 282 .tm_hour = 0, 283 .tm_mday = 1, 284 .tm_mon = Month::JANUARY, 285 .tm_year = tm_year(1971), 286 .tm_wday = 5, 287 .tm_yday = 0, 288 .tm_isdst = 0}), 289 tm_data); 290 } 291 } 292 293 TEST(LlvmLibcMkTime, InvalidDays) { 294 { 295 // -1 day from 1970-01-01 00:00:00 returns 1969-12-31 00:00:00. 296 struct tm tm_data { 297 .tm_sec = 0, .tm_min = 0, .tm_hour = 0, .tm_mday = (1 - 1), 298 .tm_mon = Month::JANUARY, .tm_year = tm_year(1970), .tm_wday = 0, 299 .tm_yday = 0, .tm_isdst = 0 300 }; 301 EXPECT_THAT(LIBC_NAMESPACE::mktime(&tm_data), 302 Succeeds(-1 * TimeConstants::SECONDS_PER_DAY)); 303 EXPECT_TM_EQ((tm{.tm_sec = 0, 304 .tm_min = 0, 305 .tm_hour = 0, 306 .tm_mday = 31, 307 .tm_mon = Month::DECEMBER, 308 .tm_year = tm_year(1969), 309 .tm_wday = 3, 310 .tm_yday = 0, 311 .tm_isdst = 0}), 312 tm_data); 313 } 314 315 { 316 // 1970-01-32 00:00:00 returns 1970-02-01 00:00:00. 317 struct tm tm_data { 318 .tm_sec = 0, .tm_min = 0, .tm_hour = 0, .tm_mday = 32, 319 .tm_mon = Month::JANUARY, .tm_year = tm_year(1970), .tm_wday = 0, 320 .tm_yday = 0, .tm_isdst = 0 321 }; 322 EXPECT_THAT(LIBC_NAMESPACE::mktime(&tm_data), 323 Succeeds(31 * TimeConstants::SECONDS_PER_DAY)); 324 EXPECT_TM_EQ((tm{.tm_sec = 0, 325 .tm_min = 0, 326 .tm_hour = 0, 327 .tm_mday = 1, 328 .tm_mon = Month::FEBRUARY, 329 .tm_year = tm_year(1970), 330 .tm_wday = 0, 331 .tm_yday = 0, 332 .tm_isdst = 0}), 333 tm_data); 334 } 335 336 { 337 // 1970-02-29 00:00:00 returns 1970-03-01 00:00:00. 338 struct tm tm_data { 339 .tm_sec = 0, .tm_min = 0, .tm_hour = 0, .tm_mday = 29, 340 .tm_mon = Month::FEBRUARY, .tm_year = tm_year(1970), .tm_wday = 0, 341 .tm_yday = 0, .tm_isdst = 0 342 }; 343 EXPECT_THAT(LIBC_NAMESPACE::mktime(&tm_data), 344 Succeeds(59 * TimeConstants::SECONDS_PER_DAY)); 345 EXPECT_TM_EQ((tm{.tm_sec = 0, 346 .tm_min = 0, 347 .tm_hour = 0, 348 .tm_mday = 1, 349 .tm_mon = Month::MARCH, 350 .tm_year = tm_year(1970), 351 .tm_wday = 0, 352 .tm_yday = 0, 353 .tm_isdst = 0}), 354 tm_data); 355 } 356 357 { 358 // 1972-02-30 00:00:00 returns 1972-03-01 00:00:00. 359 struct tm tm_data { 360 .tm_sec = 0, .tm_min = 0, .tm_hour = 0, .tm_mday = 30, 361 .tm_mon = Month::FEBRUARY, .tm_year = tm_year(1972), .tm_wday = 0, 362 .tm_yday = 0, .tm_isdst = 0 363 }; 364 EXPECT_THAT(LIBC_NAMESPACE::mktime(&tm_data), 365 Succeeds(((2 * TimeConstants::DAYS_PER_NON_LEAP_YEAR) + 60) * 366 TimeConstants::SECONDS_PER_DAY)); 367 EXPECT_TM_EQ((tm{.tm_sec = 0, 368 .tm_min = 0, 369 .tm_hour = 0, 370 .tm_mday = 1, 371 .tm_mon = Month::MARCH, 372 .tm_year = tm_year(1972), 373 .tm_wday = 3, 374 .tm_yday = 0, 375 .tm_isdst = 0}), 376 tm_data); 377 } 378 } 379 380 TEST(LlvmLibcMkTime, EndOf32BitEpochYear) { 381 // Test for maximum value of a signed 32-bit integer. 382 // Test implementation can encode time for Tue 19 January 2038 03:14:07 UTC. 383 { 384 struct tm tm_data { 385 .tm_sec = 7, .tm_min = 14, .tm_hour = 3, .tm_mday = 19, 386 .tm_mon = Month::JANUARY, .tm_year = tm_year(2038), .tm_wday = 0, 387 .tm_yday = 0, .tm_isdst = 0 388 }; 389 EXPECT_THAT(LIBC_NAMESPACE::mktime(&tm_data), Succeeds(0x7FFFFFFF)); 390 EXPECT_TM_EQ((tm{.tm_sec = 7, 391 .tm_min = 14, 392 .tm_hour = 3, 393 .tm_mday = 19, 394 .tm_mon = Month::JANUARY, 395 .tm_year = tm_year(2038), 396 .tm_wday = 2, 397 .tm_yday = 7, 398 .tm_isdst = 0}), 399 tm_data); 400 } 401 402 // Now test some times before that, to ensure they are not rejected. 403 { 404 // 2038-01-19 03:13:59 tests that even a large seconds field is 405 // accepted if the minutes field is smaller. 406 struct tm tm_data { 407 .tm_sec = 59, .tm_min = 13, .tm_hour = 3, .tm_mday = 19, 408 .tm_mon = Month::JANUARY, .tm_year = tm_year(2038), .tm_wday = 0, 409 .tm_yday = 0, .tm_isdst = 0 410 }; 411 EXPECT_THAT(LIBC_NAMESPACE::mktime(&tm_data), Succeeds(0x7FFFFFFF - 8)); 412 EXPECT_TM_EQ((tm{.tm_sec = 59, 413 .tm_min = 13, 414 .tm_hour = 3, 415 .tm_mday = 19, 416 .tm_mon = Month::JANUARY, 417 .tm_year = tm_year(2038), 418 .tm_wday = 2, 419 .tm_yday = 7, 420 .tm_isdst = 0}), 421 tm_data); 422 } 423 424 { 425 // 2038-01-19 02:59:59 tests that large seconds and minutes are 426 // accepted if the hours field is smaller. 427 struct tm tm_data { 428 .tm_sec = 59, .tm_min = 59, .tm_hour = 2, .tm_mday = 19, 429 .tm_mon = Month::JANUARY, .tm_year = tm_year(2038), .tm_wday = 0, 430 .tm_yday = 0, .tm_isdst = 0 431 }; 432 EXPECT_THAT(LIBC_NAMESPACE::mktime(&tm_data), 433 Succeeds(0x7FFFFFFF - 8 - 14 * TimeConstants::SECONDS_PER_MIN)); 434 EXPECT_TM_EQ((tm{.tm_sec = 59, 435 .tm_min = 59, 436 .tm_hour = 2, 437 .tm_mday = 19, 438 .tm_mon = Month::JANUARY, 439 .tm_year = tm_year(2038), 440 .tm_wday = 2, 441 .tm_yday = 7, 442 .tm_isdst = 0}), 443 tm_data); 444 } 445 446 { 447 // 2038-01-18 23:59:59 tests that large seconds, minutes and hours 448 // are accepted if the days field is smaller. 449 struct tm tm_data { 450 .tm_sec = 59, .tm_min = 59, .tm_hour = 23, .tm_mday = 18, 451 .tm_mon = Month::JANUARY, .tm_year = tm_year(2038), .tm_wday = 0, 452 .tm_yday = 0, .tm_isdst = 0 453 }; 454 EXPECT_THAT(LIBC_NAMESPACE::mktime(&tm_data), 455 Succeeds(0x7FFFFFFF - 8 - 14 * TimeConstants::SECONDS_PER_MIN - 456 3 * TimeConstants::SECONDS_PER_HOUR)); 457 EXPECT_TM_EQ((tm{.tm_sec = 59, 458 .tm_min = 59, 459 .tm_hour = 23, 460 .tm_mday = 18, 461 .tm_mon = Month::JANUARY, 462 .tm_year = tm_year(2038), 463 .tm_wday = 2, 464 .tm_yday = 7, 465 .tm_isdst = 0}), 466 tm_data); 467 } 468 469 { 470 // 2038-01-18 23:59:59 tests that the final second of 2037 is 471 // accepted. 472 struct tm tm_data { 473 .tm_sec = 59, .tm_min = 59, .tm_hour = 23, .tm_mday = 31, 474 .tm_mon = Month::DECEMBER, .tm_year = tm_year(2037), .tm_wday = 0, 475 .tm_yday = 0, .tm_isdst = 0 476 }; 477 EXPECT_THAT(LIBC_NAMESPACE::mktime(&tm_data), 478 Succeeds(0x7FFFFFFF - 8 - 14 * TimeConstants::SECONDS_PER_MIN - 479 3 * TimeConstants::SECONDS_PER_HOUR - 480 18 * TimeConstants::SECONDS_PER_DAY)); 481 EXPECT_TM_EQ((tm{.tm_sec = 59, 482 .tm_min = 59, 483 .tm_hour = 23, 484 .tm_mday = 31, 485 .tm_mon = Month::DECEMBER, 486 .tm_year = tm_year(2037), 487 .tm_wday = 2, 488 .tm_yday = 7, 489 .tm_isdst = 0}), 490 tm_data); 491 } 492 } 493 494 TEST(LlvmLibcMkTime, Max64BitYear) { 495 if (sizeof(time_t) == 4) 496 return; 497 { 498 // Mon Jan 1 12:50:50 2170 (200 years from 1970), 499 struct tm tm_data { 500 .tm_sec = 50, .tm_min = 50, .tm_hour = 12, .tm_mday = 1, 501 .tm_mon = Month::JANUARY, .tm_year = tm_year(2170), .tm_wday = 0, 502 .tm_yday = 0, .tm_isdst = 0 503 }; 504 EXPECT_THAT(LIBC_NAMESPACE::mktime(&tm_data), Succeeds(6311479850)); 505 EXPECT_TM_EQ((tm{.tm_sec = 50, 506 .tm_min = 50, 507 .tm_hour = 12, 508 .tm_mday = 1, 509 .tm_mon = Month::JANUARY, 510 .tm_year = tm_year(2170), 511 .tm_wday = 1, 512 .tm_yday = 50, 513 .tm_isdst = 0}), 514 tm_data); 515 } 516 517 { 518 // Test for Tue Jan 1 12:50:50 in 2,147,483,647th year. 519 struct tm tm_data { 520 .tm_sec = 50, .tm_min = 50, .tm_hour = 12, .tm_mday = 1, 521 .tm_mon = Month::JANUARY, .tm_year = tm_year(2147483647), .tm_wday = 0, 522 .tm_yday = 0, .tm_isdst = 0 523 }; 524 EXPECT_THAT(LIBC_NAMESPACE::mktime(&tm_data), Succeeds(67767976202043050)); 525 EXPECT_TM_EQ((tm{.tm_sec = 50, 526 .tm_min = 50, 527 .tm_hour = 12, 528 .tm_mday = 1, 529 .tm_mon = Month::JANUARY, 530 .tm_year = tm_year(2147483647), 531 .tm_wday = 2, 532 .tm_yday = 50, 533 .tm_isdst = 0}), 534 tm_data); 535 } 536 } 537