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