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