xref: /aosp_15_r20/external/llvm-libc/test/src/time/mktime_test.cpp (revision 71db0c75aadcf003ffe3238005f61d7618a3fead)
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 
tm_year(int year)21 static inline constexpr int tm_year(int year) {
22   return year - TimeConstants::TIME_YEAR_BASE;
23 }
24 
TEST(LlvmLibcMkTime,FailureSetsErrno)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 
TEST(LlvmLibcMkTime,InvalidSeconds)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 
TEST(LlvmLibcMkTime,InvalidMinutes)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 
TEST(LlvmLibcMkTime,InvalidHours)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 
TEST(LlvmLibcMkTime,InvalidYear)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 
TEST(LlvmLibcMkTime,InvalidEndOf32BitEpochYear)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 
TEST(LlvmLibcMkTime,InvalidMonths)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 
TEST(LlvmLibcMkTime,InvalidDays)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 
TEST(LlvmLibcMkTime,EndOf32BitEpochYear)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 
TEST(LlvmLibcMkTime,Max64BitYear)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