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