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
17using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
18using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
19using LIBC_NAMESPACE::time_utils::TimeConstants;
20
21TEST(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(timer: &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(timer: &seconds);
36 EXPECT_TRUE(tm_data == nullptr);
37 ASSERT_ERRNO_EQ(EOVERFLOW);
38}
39
40TEST(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(timer: &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(timer: &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
71TEST(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(timer: &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(timer: &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
102TEST(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(timer: &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(timer: &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
133TEST(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(timer: &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
150TEST(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(timer: &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(timer: &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
182TEST(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(timer: &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(timer: &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(timer: &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(timer: &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
243TEST(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(timer: &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
260TEST(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(timer: &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(timer: &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

source code of libc/test/src/time/gmtime_test.cpp