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