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