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