VirtualBox

source: vbox/trunk/src/VBox/Runtime/testcase/tstRTTimeSpec.cpp@ 100838

Last change on this file since 100838 was 99775, checked in by vboxsync, 19 months ago

*: Mark functions as static if not used outside of a given compilation unit. Enables the compiler to optimize inlining, reduces the symbol tables, exposes unused functions and in some rare cases exposes mismtaches between function declarations and definitions, but most importantly reduces the number of parfait reports for the extern-function-no-forward-declaration category. This should not result in any functional changes, bugref:3409

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 39.5 KB
Line 
1/* $Id: tstRTTimeSpec.cpp 99775 2023-05-12 12:21:58Z vboxsync $ */
2/** @file
3 * IPRT - RTTimeSpec and PRTTIME tests.
4 */
5
6/*
7 * Copyright (C) 2006-2023 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * The contents of this file may alternatively be used under the terms
26 * of the Common Development and Distribution License Version 1.0
27 * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
28 * in the VirtualBox distribution, in which case the provisions of the
29 * CDDL are applicable instead of those of the GPL.
30 *
31 * You may elect to license modified versions of this file under the
32 * terms and conditions of either the GPL or the CDDL or both.
33 *
34 * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
35 */
36
37
38/*********************************************************************************************************************************
39* Header Files *
40*********************************************************************************************************************************/
41#if !defined(RT_OS_WINDOWS)
42# define RTTIME_INCL_TIMEVAL
43# define RTTIME_INCL_TIMESPEC
44# include <time.h>
45# include <sys/time.h>
46#endif
47#include <iprt/time.h>
48
49#include <iprt/rand.h>
50#include <iprt/test.h>
51#include <iprt/string.h>
52
53
54/**
55 * Format the time into a string using a static buffer.
56 */
57static char *ToString(PRTTIME pTime)
58{
59 static char szBuf[128];
60 RTStrPrintf(szBuf, sizeof(szBuf), "%04d-%02d-%02dT%02u:%02u:%02u.%09u [YD%u WD%u UO%d F%#x]",
61 pTime->i32Year,
62 pTime->u8Month,
63 pTime->u8MonthDay,
64 pTime->u8Hour,
65 pTime->u8Minute,
66 pTime->u8Second,
67 pTime->u32Nanosecond,
68 pTime->u16YearDay,
69 pTime->u8WeekDay,
70 pTime->offUTC,
71 pTime->fFlags);
72 return szBuf;
73}
74
75#define CHECK_NZ(expr) do { if (!(expr)) { RTTestIFailed("at line %d: %#x\n", __LINE__, #expr); return RTTestSummaryAndDestroy(hTest); } } while (0)
76
77#define TEST_NS(ns) do {\
78 CHECK_NZ(RTTimeExplode(&T1, RTTimeSpecSetNano(&Ts1, ns))); \
79 RTTestIPrintf(RTTESTLVL_ALWAYS, "%RI64 ns - %s\n", ns, ToString(&T1)); \
80 CHECK_NZ(RTTimeImplode(&Ts2, &T1)); \
81 if (!RTTimeSpecIsEqual(&Ts2, &Ts1)) \
82 RTTestIFailed("FAILURE - %RI64 != %RI64, line no. %d\n", \
83 RTTimeSpecGetNano(&Ts2), RTTimeSpecGetNano(&Ts1), __LINE__); \
84 } while (0)
85
86#define TEST_NS_LOCAL(ns) do {\
87 CHECK_NZ(RTTimeLocalExplode(&T1, RTTimeSpecSetNano(&Ts1, ns))); \
88 RTTestIPrintf(RTTESTLVL_ALWAYS, "%RI64 ns - %s\n", ns, ToString(&T1)); \
89 CHECK_NZ(RTTimeImplode(&Ts2, &T1)); \
90 if (!RTTimeSpecIsEqual(&Ts2, &Ts1)) \
91 RTTestIFailed("FAILURE - %RI64 != %RI64, line no. %d\n", \
92 RTTimeSpecGetNano(&Ts2), RTTimeSpecGetNano(&Ts1), __LINE__); \
93 } while (0)
94
95#define TEST_SEC(sec) do {\
96 CHECK_NZ(RTTimeExplode(&T1, RTTimeSpecSetSeconds(&Ts1, sec))); \
97 RTTestIPrintf(RTTESTLVL_ALWAYS, "%RI64 sec - %s\n", sec, ToString(&T1)); \
98 CHECK_NZ(RTTimeImplode(&Ts2, &T1)); \
99 if (!RTTimeSpecIsEqual(&Ts2, &Ts1)) \
100 RTTestIFailed("FAILURE - %RI64 != %RI64, line no. %d\n", \
101 RTTimeSpecGetNano(&Ts2), RTTimeSpecGetNano(&Ts1), __LINE__); \
102 } while (0)
103
104#define CHECK_TIME_EX(pTime, _i32Year, _u8Month, _u8MonthDay, _u8Hour, _u8Minute, _u8Second, _u32Nanosecond, _u16YearDay, _u8WeekDay, _offUTC, _fFlags, _Silent)\
105 do { \
106 if ( (pTime)->i32Year != (_i32Year) \
107 || (pTime)->u8Month != (_u8Month) \
108 || (pTime)->u8WeekDay != (_u8WeekDay) \
109 || (pTime)->u16YearDay != (_u16YearDay) \
110 || (pTime)->u8MonthDay != (_u8MonthDay) \
111 || (pTime)->u8Hour != (_u8Hour) \
112 || (pTime)->u8Minute != (_u8Minute) \
113 || (pTime)->u8Second != (_u8Second) \
114 || (pTime)->u32Nanosecond != (_u32Nanosecond) \
115 || (pTime)->offUTC != (_offUTC) \
116 || (pTime)->fFlags != (_fFlags) \
117 ) \
118 { \
119 RTTestIFailed(" %s ; line no %d\n" \
120 "!= %04d-%02d-%02dT%02u:%02u:%02u.%09u [YD%u WD%u UO%d F%#x]\n", \
121 ToString(pTime), __LINE__, (_i32Year), (_u8Month), (_u8MonthDay), (_u8Hour), (_u8Minute), \
122 (_u8Second), (_u32Nanosecond), (_u16YearDay), (_u8WeekDay), (_offUTC), (_fFlags)); \
123 } \
124 else if (!_Silent) \
125 RTTestIPrintf(RTTESTLVL_ALWAYS, "=> %s\n", ToString(pTime)); \
126 } while (0)
127#define CHECK_TIME(pTime, _i32Year, _u8Month, _u8MonthDay, _u8Hour, _u8Minute, _u8Second, _u32Nanosecond, _u16YearDay, _u8WeekDay, _offUTC, _fFlags) CHECK_TIME_EX(pTime, _i32Year, _u8Month, _u8MonthDay, _u8Hour, _u8Minute, _u8Second, _u32Nanosecond, _u16YearDay, _u8WeekDay, _offUTC, _fFlags, false)
128#define CHECK_TIME_SILENT(pTime, _i32Year, _u8Month, _u8MonthDay, _u8Hour, _u8Minute, _u8Second, _u32Nanosecond, _u16YearDay, _u8WeekDay, _offUTC, _fFlags) CHECK_TIME_EX(pTime, _i32Year, _u8Month, _u8MonthDay, _u8Hour, _u8Minute, _u8Second, _u32Nanosecond, _u16YearDay, _u8WeekDay, _offUTC, _fFlags, true)
129
130#define CHECK_TIME_LOCAL_EX(pTime, _i32Year, _u8Month, _u8MonthDay, _u8Hour, _u8Minute, _u8Second, _u32Nanosecond, _u16YearDay, _u8WeekDay, _offUTC, _fFlags, _Silent)\
131 do { \
132 uint32_t fOrigFlags = (pTime)->fFlags; \
133 CHECK_NZ(RTTimeConvertToZulu(pTime)); \
134 if ( (pTime)->i32Year != (_i32Year) \
135 || (pTime)->u8Month != (_u8Month) \
136 || (pTime)->u8WeekDay != (_u8WeekDay) \
137 || (pTime)->u16YearDay != (_u16YearDay) \
138 || (pTime)->u8MonthDay != (_u8MonthDay) \
139 || (pTime)->u8Hour != (_u8Hour) \
140 || (pTime)->u8Minute != (_u8Minute) \
141 || (pTime)->u8Second != (_u8Second) \
142 || (pTime)->u32Nanosecond != (_u32Nanosecond) \
143 || (pTime)->offUTC != (_offUTC) \
144 || (fOrigFlags & RTTIME_FLAGS_TYPE_MASK) != RTTIME_FLAGS_TYPE_LOCAL \
145 || (pTime)->fFlags != (_fFlags) \
146 ) \
147 { \
148 RTTestIFailed(" %s ; line no %d\n" \
149 "!= %04d-%02d-%02dT%02u:%02u:%02u.%09u [YD%u WD%u UO%d F%#x]\n", \
150 ToString(pTime), __LINE__, (_i32Year), (_u8Month), (_u8MonthDay), (_u8Hour), (_u8Minute), \
151 (_u8Second), (_u32Nanosecond), (_u16YearDay), (_u8WeekDay), (_offUTC), (_fFlags)); \
152 } \
153 else if (!_Silent) \
154 RTTestIPrintf(RTTESTLVL_ALWAYS, "=> %s\n", ToString(pTime)); \
155 } while (0)
156#define CHECK_TIME_LOCAL(pTime, _i32Year, _u8Month, _u8MonthDay, _u8Hour, _u8Minute, _u8Second, _u32Nanosecond, _u16YearDay, _u8WeekDay, _offUTC, _fFlags) CHECK_TIME_LOCAL_EX(pTime, _i32Year, _u8Month, _u8MonthDay, _u8Hour, _u8Minute, _u8Second, _u32Nanosecond, _u16YearDay, _u8WeekDay, _offUTC, _fFlags, false)
157#define CHECK_TIME_LOCAL_SILENT(pTime, _i32Year, _u8Month, _u8MonthDay, _u8Hour, _u8Minute, _u8Second, _u32Nanosecond, _u16YearDay, _u8WeekDay, _offUTC, _fFlags) CHECK_TIME_LOCAL_EX(pTime, _i32Year, _u8Month, _u8MonthDay, _u8Hour, _u8Minute, _u8Second, _u32Nanosecond, _u16YearDay, _u8WeekDay, _offUTC, _fFlags, true)
158
159#define SET_TIME(pTime, _i32Year, _u8Month, _u8MonthDay, _u8Hour, _u8Minute, _u8Second, _u32Nanosecond, _u16YearDay, _u8WeekDay, _offUTC, _fFlags)\
160 do { \
161 (pTime)->i32Year = (_i32Year); \
162 (pTime)->u8Month = (_u8Month); \
163 (pTime)->u8WeekDay = (_u8WeekDay); \
164 (pTime)->u16YearDay = (_u16YearDay); \
165 (pTime)->u8MonthDay = (_u8MonthDay); \
166 (pTime)->u8Hour = (_u8Hour); \
167 (pTime)->u8Minute = (_u8Minute); \
168 (pTime)->u8Second = (_u8Second); \
169 (pTime)->u32Nanosecond = (_u32Nanosecond); \
170 (pTime)->offUTC = (_offUTC); \
171 (pTime)->fFlags = (_fFlags); \
172 RTTestIPrintf(RTTESTLVL_ALWAYS, " %s\n", ToString(pTime)); \
173 } while (0)
174
175
176int main()
177{
178 RTTIMESPEC Now;
179 RTTIMESPEC Ts1;
180 RTTIMESPEC Ts2;
181 RTTIME T1;
182 RTTIME T2;
183#ifdef RTTIME_INCL_TIMEVAL
184 struct timeval Tv1;
185 struct timeval Tv2;
186 struct timespec Tsp1;
187 struct timespec Tsp2;
188#endif
189 RTTEST hTest;
190
191 int rc = RTTestInitAndCreate("tstRTTimeSpec", &hTest);
192 if (rc)
193 return rc;
194
195 /*
196 * Simple test with current time.
197 */
198 RTTestSub(hTest, "Current time (UTC)");
199 CHECK_NZ(RTTimeNow(&Now));
200 CHECK_NZ(RTTimeExplode(&T1, &Now));
201 RTTestIPrintf(RTTESTLVL_ALWAYS, " %RI64 ns - %s\n", RTTimeSpecGetNano(&Now), ToString(&T1));
202 CHECK_NZ(RTTimeImplode(&Ts1, &T1));
203 if (!RTTimeSpecIsEqual(&Ts1, &Now))
204 RTTestIFailed("%RI64 != %RI64\n", RTTimeSpecGetNano(&Ts1), RTTimeSpecGetNano(&Now));
205
206 /*
207 * Simple test with current local time.
208 */
209 RTTestSub(hTest, "Current time (local)");
210 CHECK_NZ(RTTimeLocalNow(&Now));
211 CHECK_NZ(RTTimeExplode(&T1, &Now));
212 RTTestIPrintf(RTTESTLVL_ALWAYS, " %RI64 ns - %s\n", RTTimeSpecGetNano(&Now), ToString(&T1));
213 CHECK_NZ(RTTimeImplode(&Ts1, &T1));
214 if (!RTTimeSpecIsEqual(&Ts1, &Now))
215 RTTestIFailed("%RI64 != %RI64\n", RTTimeSpecGetNano(&Ts1), RTTimeSpecGetNano(&Now));
216
217 /*
218 * Some simple tests with fixed dates (just checking for smoke).
219 */
220 RTTestSub(hTest, "Smoke");
221 TEST_NS(INT64_C(0));
222 CHECK_TIME(&T1, 1970,01,01, 00,00,00, 0, 1, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
223 TEST_NS(INT64_C(86400000000000));
224 CHECK_TIME(&T1, 1970,01,02, 00,00,00, 0, 2, 4, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
225
226 TEST_NS(INT64_C(1));
227 CHECK_TIME(&T1, 1970,01,01, 00,00,00, 1, 1, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
228 TEST_NS(INT64_C(-1));
229 CHECK_TIME(&T1, 1969,12,31, 23,59,59,999999999, 365, 2, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
230
231 /*
232 * Some local time tests with dates triggering unexpected wraparound bugs in previous code version
233 * (on 2nd of a month). Test every hour to cover any TZ of the host OS.
234 */
235 RTTestSub(hTest, "Wraparound (local)");
236 TEST_NS_LOCAL(INT64_C(1522576800000000000));
237 CHECK_TIME_LOCAL(&T1, 2018,04,01, 10,00,00, 0, 91, 6, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
238 TEST_NS_LOCAL(INT64_C(1522580400000000000));
239 CHECK_TIME_LOCAL(&T1, 2018,04,01, 11,00,00, 0, 91, 6, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
240 TEST_NS_LOCAL(INT64_C(1522584000000000000));
241 CHECK_TIME_LOCAL(&T1, 2018,04,01, 12,00,00, 0, 91, 6, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
242 TEST_NS_LOCAL(INT64_C(1522587600000000000));
243 CHECK_TIME_LOCAL(&T1, 2018,04,01, 13,00,00, 0, 91, 6, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
244 TEST_NS_LOCAL(INT64_C(1522591200000000000));
245 CHECK_TIME_LOCAL(&T1, 2018,04,01, 14,00,00, 0, 91, 6, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
246 TEST_NS_LOCAL(INT64_C(1522594800000000000));
247 CHECK_TIME_LOCAL(&T1, 2018,04,01, 15,00,00, 0, 91, 6, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
248 TEST_NS_LOCAL(INT64_C(1522598400000000000));
249 CHECK_TIME_LOCAL(&T1, 2018,04,01, 16,00,00, 0, 91, 6, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
250 TEST_NS_LOCAL(INT64_C(1522602000000000000));
251 CHECK_TIME_LOCAL(&T1, 2018,04,01, 17,00,00, 0, 91, 6, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
252 TEST_NS_LOCAL(INT64_C(1522605600000000000));
253 CHECK_TIME_LOCAL(&T1, 2018,04,01, 18,00,00, 0, 91, 6, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
254 TEST_NS_LOCAL(INT64_C(1522609200000000000));
255 CHECK_TIME_LOCAL(&T1, 2018,04,01, 19,00,00, 0, 91, 6, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
256 TEST_NS_LOCAL(INT64_C(1522612800000000000));
257 CHECK_TIME_LOCAL(&T1, 2018,04,01, 20,00,00, 0, 91, 6, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
258 TEST_NS_LOCAL(INT64_C(1522616400000000000));
259 CHECK_TIME_LOCAL(&T1, 2018,04,01, 21,00,00, 0, 91, 6, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
260 TEST_NS_LOCAL(INT64_C(1522620000000000000));
261 CHECK_TIME_LOCAL(&T1, 2018,04,01, 22,00,00, 0, 91, 6, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
262 TEST_NS_LOCAL(INT64_C(1522623600000000000));
263 CHECK_TIME_LOCAL(&T1, 2018,04,01, 23,00,00, 0, 91, 6, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
264 TEST_NS_LOCAL(INT64_C(1522627200000000000));
265 CHECK_TIME_LOCAL(&T1, 2018,04,02, 0,00,00, 0, 92, 0, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
266 TEST_NS_LOCAL(INT64_C(1522630800000000000));
267 CHECK_TIME_LOCAL(&T1, 2018,04,02, 1,00,00, 0, 92, 0, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
268 TEST_NS_LOCAL(INT64_C(1522634400000000000));
269 CHECK_TIME_LOCAL(&T1, 2018,04,02, 2,00,00, 0, 92, 0, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
270 TEST_NS_LOCAL(INT64_C(1522638000000000000));
271 CHECK_TIME_LOCAL(&T1, 2018,04,02, 3,00,00, 0, 92, 0, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
272 TEST_NS_LOCAL(INT64_C(1522641600000000000));
273 CHECK_TIME_LOCAL(&T1, 2018,04,02, 4,00,00, 0, 92, 0, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
274 TEST_NS_LOCAL(INT64_C(1522645200000000000));
275 CHECK_TIME_LOCAL(&T1, 2018,04,02, 5,00,00, 0, 92, 0, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
276 TEST_NS_LOCAL(INT64_C(1522648800000000000));
277 CHECK_TIME_LOCAL(&T1, 2018,04,02, 6,00,00, 0, 92, 0, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
278 TEST_NS_LOCAL(INT64_C(1522652400000000000));
279 CHECK_TIME_LOCAL(&T1, 2018,04,02, 7,00,00, 0, 92, 0, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
280 TEST_NS_LOCAL(INT64_C(1522656000000000000));
281 CHECK_TIME_LOCAL(&T1, 2018,04,02, 8,00,00, 0, 92, 0, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
282 TEST_NS_LOCAL(INT64_C(1522659600000000000));
283 CHECK_TIME_LOCAL(&T1, 2018,04,02, 9,00,00, 0, 92, 0, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
284 TEST_NS_LOCAL(INT64_C(1522663200000000000));
285 CHECK_TIME_LOCAL(&T1, 2018,04,02, 10,00,00, 0, 92, 0, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
286 TEST_NS_LOCAL(INT64_C(1522666800000000000));
287 CHECK_TIME_LOCAL(&T1, 2018,04,02, 11,00,00, 0, 92, 0, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
288 TEST_NS_LOCAL(INT64_C(1522670400000000000));
289 CHECK_TIME_LOCAL(&T1, 2018,04,02, 12,00,00, 0, 92, 0, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
290 TEST_NS_LOCAL(INT64_C(1522674000000000000));
291 CHECK_TIME_LOCAL(&T1, 2018,04,02, 13,00,00, 0, 92, 0, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
292 TEST_NS_LOCAL(INT64_C(1522677600000000000));
293 CHECK_TIME_LOCAL(&T1, 2018,04,02, 14,00,00, 0, 92, 0, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
294
295 /*
296 * Test the limits.
297 */
298 RTTestSub(hTest, "Extremes");
299 TEST_NS(INT64_MAX);
300 TEST_NS(INT64_MIN);
301 TEST_SEC(INT64_C(1095379198));
302 CHECK_TIME(&T1, 2004, 9,16, 23,59,58, 0, 260, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_LEAP_YEAR);
303 TEST_SEC(INT64_C(1095379199));
304 CHECK_TIME(&T1, 2004, 9,16, 23,59,59, 0, 260, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_LEAP_YEAR);
305 TEST_SEC(INT64_C(1095379200));
306 CHECK_TIME(&T1, 2004, 9,17, 00,00,00, 0, 261, 4, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_LEAP_YEAR);
307 TEST_SEC(INT64_C(1095379201));
308 CHECK_TIME(&T1, 2004, 9,17, 00,00,01, 0, 261, 4, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_LEAP_YEAR);
309
310 /*
311 * Test normalization (UTC).
312 */
313 RTTestSub(hTest, "Normalization (UTC)");
314 /* simple */
315 CHECK_NZ(RTTimeNow(&Now));
316 CHECK_NZ(RTTimeExplode(&T1, &Now));
317 T2 = T1;
318 CHECK_NZ(RTTimeNormalize(&T1));
319 if (memcmp(&T1, &T2, sizeof(T1)))
320 RTTestIFailed("simple normalization failed\n");
321 CHECK_NZ(RTTimeImplode(&Ts1, &T1));
322 CHECK_NZ(RTTimeSpecIsEqual(&Ts1, &Now));
323
324 /* a few partial dates. */
325 memset(&T1, 0, sizeof(T1));
326 SET_TIME( &T1, 1970,01,01, 00,00,00, 0, 0, 0, 0, 0);
327 CHECK_NZ(RTTimeNormalize(&T1));
328 CHECK_TIME(&T1, 1970,01,01, 00,00,00, 0, 1, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
329
330 SET_TIME( &T1, 1970,00,00, 00,00,00, 1, 1, 0, 0, 0);
331 CHECK_NZ(RTTimeNormalize(&T1));
332 CHECK_TIME(&T1, 1970,01,01, 00,00,00, 1, 1, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
333
334 SET_TIME( &T1, 2007,12,06, 02,15,23, 1, 0, 0, 0, 0);
335 CHECK_NZ(RTTimeNormalize(&T1));
336 CHECK_TIME(&T1, 2007,12,06, 02,15,23, 1, 340, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
337
338 SET_TIME( &T1, 1968,01,30, 00,19,24, 5, 0, 0, 0, 0);
339 CHECK_NZ(RTTimeNormalize(&T1));
340 CHECK_TIME(&T1, 1968,01,30, 00,19,24, 5, 30, 1, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_LEAP_YEAR);
341
342 SET_TIME( &T1, 1969,01,31, 00, 9, 2, 7, 0, 0, 0, 0);
343 CHECK_NZ(RTTimeNormalize(&T1));
344 CHECK_TIME(&T1, 1969,01,31, 00, 9, 2, 7, 31, 4, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
345
346 SET_TIME( &T1, 1969,03,31, 00, 9, 2, 7, 0, 0, 0, 0);
347 CHECK_NZ(RTTimeNormalize(&T1));
348 CHECK_TIME(&T1, 1969,03,31, 00, 9, 2, 7, 90, 0, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
349
350 SET_TIME( &T1, 1969,12,31, 00,00,00, 9, 0, 0, 0, 0);
351 CHECK_NZ(RTTimeNormalize(&T1));
352 CHECK_TIME(&T1, 1969,12,31, 00,00,00, 9, 365, 2, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
353
354 SET_TIME( &T1, 1969,12,30, 00,00,00, 30, 0, 0, 0, 0);
355 CHECK_NZ(RTTimeNormalize(&T1));
356 CHECK_TIME(&T1, 1969,12,30, 00,00,00, 30, 364, 1, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
357
358 SET_TIME( &T1, 1969,00,00, 00,00,00, 30, 363, 0, 0, 0);
359 CHECK_NZ(RTTimeNormalize(&T1));
360 CHECK_TIME(&T1, 1969,12,29, 00,00,00, 30, 363, 0, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
361
362 SET_TIME( &T1, 1969,00,00, 00,00,00, 30, 362, 6, 0, 0);
363 CHECK_NZ(RTTimeNormalize(&T1));
364 CHECK_TIME(&T1, 1969,12,28, 00,00,00, 30, 362, 6, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
365
366 SET_TIME( &T1, 1969,12,27, 00,00,00, 30, 0, 5, 0, 0);
367 CHECK_NZ(RTTimeNormalize(&T1));
368 CHECK_TIME(&T1, 1969,12,27, 00,00,00, 30, 361, 5, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
369
370 SET_TIME( &T1, 1969,00,00, 00,00,00, 30, 360, 0, 0, 0);
371 CHECK_NZ(RTTimeNormalize(&T1));
372 CHECK_TIME(&T1, 1969,12,26, 00,00,00, 30, 360, 4, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
373
374 SET_TIME( &T1, 1969,12,25, 00,00,00, 12, 0, 0, 0, 0);
375 CHECK_NZ(RTTimeNormalize(&T1));
376 CHECK_TIME(&T1, 1969,12,25, 00,00,00, 12, 359, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
377
378 SET_TIME( &T1, 1969,12,24, 00,00,00, 16, 0, 0, 0, 0);
379 CHECK_NZ(RTTimeNormalize(&T1));
380 CHECK_TIME(&T1, 1969,12,24, 00,00,00, 16, 358, 2, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
381
382 /* outside the year table range */
383 SET_TIME( &T1, 1200,01,30, 00,00,00, 2, 0, 0, 0, 0);
384 CHECK_NZ(RTTimeNormalize(&T1));
385 CHECK_TIME(&T1, 1200,01,30, 00,00,00, 2, 30, 6, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_LEAP_YEAR);
386
387 SET_TIME( &T1, 2555,11,29, 00,00,00, 2, 0, 0, 0, 0);
388 CHECK_NZ(RTTimeNormalize(&T1));
389 CHECK_TIME(&T1, 2555,11,29, 00,00,00, 2, 333, 5, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
390
391 SET_TIME( &T1, 2555,00,00, 00,00,00, 3, 333, 0, 0, 0);
392 CHECK_NZ(RTTimeNormalize(&T1));
393 CHECK_TIME(&T1, 2555,11,29, 00,00,00, 3, 333, 5, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
394
395 /* time overflow */
396 SET_TIME( &T1, 1969,12,30, 255,255,255, UINT32_MAX, 364, 0, 0, 0);
397 CHECK_NZ(RTTimeNormalize(&T1));
398 CHECK_TIME(&T1, 1970,01, 9, 19,19,19,294967295, 9, 4, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
399
400 /* date overflow */
401 SET_TIME( &T1, 2007,11,36, 02,15,23, 1, 0, 0, 0, 0);
402 CHECK_NZ(RTTimeNormalize(&T1));
403 CHECK_TIME(&T1, 2007,12,06, 02,15,23, 1, 340, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
404
405 SET_TIME( &T1, 2007,10,67, 02,15,23, 1, 0, 0, 0, 0);
406 CHECK_NZ(RTTimeNormalize(&T1));
407 CHECK_TIME(&T1, 2007,12,06, 02,15,23, 1, 340, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
408
409 SET_TIME( &T1, 2007,10,98, 02,15,23, 1, 0, 0, 0, 0);
410 CHECK_NZ(RTTimeNormalize(&T1));
411 CHECK_TIME(&T1, 2008,01,06, 02,15,23, 1, 6, 6, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_LEAP_YEAR);
412
413 SET_TIME( &T1, 2006,24,06, 02,15,23, 1, 0, 0, 0, 0);
414 CHECK_NZ(RTTimeNormalize(&T1));
415 CHECK_TIME(&T1, 2007,12,06, 02,15,23, 1, 340, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
416
417 SET_TIME( &T1, 2003,60,37, 02,15,23, 1, 0, 0, 0, 0);
418 CHECK_NZ(RTTimeNormalize(&T1));
419 CHECK_TIME(&T1, 2008,01,06, 02,15,23, 1, 6, 6, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_LEAP_YEAR);
420
421 SET_TIME( &T1, 2003,00,00, 02,15,23, 1,1801, 0, 0, 0);
422 CHECK_NZ(RTTimeNormalize(&T1));
423 CHECK_TIME(&T1, 2007,12,06, 02,15,23, 1, 340, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
424
425 /*
426 * Test normalization (local).
427 */
428 RTTestSub(hTest, "Normalization (local)");
429 /* simple */
430 CHECK_NZ(RTTimeNow(&Now));
431 CHECK_NZ(RTTimeLocalExplode(&T1, &Now));
432 T2 = T1;
433 CHECK_NZ(RTTimeLocalNormalize(&T1));
434 if (memcmp(&T1, &T2, sizeof(T1)))
435 RTTestIFailed("simple normalization failed\n");
436 CHECK_NZ(RTTimeImplode(&Ts1, &T1));
437 CHECK_NZ(RTTimeSpecIsEqual(&Ts1, &Now));
438
439 /* a few partial dates. */
440 memset(&T1, 0, sizeof(T1));
441 SET_TIME( &T1, 1970,01,01, 00,00,00, 0, 0, 0, -60, 0);
442 CHECK_NZ(RTTimeLocalNormalize(&T1));
443 CHECK_TIME_LOCAL(&T1, 1970,01,01, 01,00,00, 0, 1, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
444
445 SET_TIME( &T1, 1970,00,00, 00,00,00, 1, 1, 0, -120, 0);
446 CHECK_NZ(RTTimeLocalNormalize(&T1));
447 CHECK_TIME_LOCAL(&T1, 1970,01,01, 02,00,00, 1, 1, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
448
449 SET_TIME( &T1, 2007,12,06, 02,15,23, 1, 0, 0, 120, 0);
450 CHECK_NZ(RTTimeLocalNormalize(&T1));
451 CHECK_TIME_LOCAL(&T1, 2007,12,06, 00,15,23, 1, 340, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
452
453 SET_TIME( &T1, 1968,01,30, 00,19,24, 5, 0, 0, -480, 0);
454 CHECK_NZ(RTTimeLocalNormalize(&T1));
455 CHECK_TIME_LOCAL(&T1, 1968,01,30, 8,19,24, 5, 30, 1, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_LEAP_YEAR);
456
457 SET_TIME( &T1, 1969,01,31, 03, 9, 2, 7, 0, 0, 180, 0);
458 CHECK_NZ(RTTimeLocalNormalize(&T1));
459 CHECK_TIME_LOCAL(&T1, 1969,01,31, 00, 9, 2, 7, 31, 4, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
460
461 SET_TIME( &T1, 1969,03,31, 00, 9, 2, 7, 0, 0, -60, 0);
462 CHECK_NZ(RTTimeLocalNormalize(&T1));
463 CHECK_TIME_LOCAL(&T1, 1969,03,31, 01, 9, 2, 7, 90, 0, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
464
465 SET_TIME( &T1, 1969,12,30, 18,00,00, 9, 0, 0, -360, 0);
466 CHECK_NZ(RTTimeLocalNormalize(&T1));
467 CHECK_TIME_LOCAL(&T1, 1969,12,31, 00,00,00, 9, 365, 2, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
468
469 SET_TIME( &T1, 1969,12,29, 12,00,00, 30, 0, 0, -720, 0);
470 CHECK_NZ(RTTimeLocalNormalize(&T1));
471 CHECK_TIME_LOCAL(&T1, 1969,12,30, 00,00,00, 30, 364, 1, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
472
473 SET_TIME( &T1, 1969,00,00, 00,00,00, 30, 363, 0, 30, 0);
474 CHECK_NZ(RTTimeLocalNormalize(&T1));
475 CHECK_TIME_LOCAL(&T1, 1969,12,28, 23,30,00, 30, 362, 6, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
476
477 SET_TIME( &T1, 1969,00,00, 00,00,00, 30, 362, 6, -60, 0);
478 CHECK_NZ(RTTimeLocalNormalize(&T1));
479 CHECK_TIME_LOCAL(&T1, 1969,12,28, 01,00,00, 30, 362, 6, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
480
481 SET_TIME( &T1, 1969,12,27, 00,00,00, 30, 0, 5, -120, 0);
482 CHECK_NZ(RTTimeLocalNormalize(&T1));
483 CHECK_TIME_LOCAL(&T1, 1969,12,27, 02,00,00, 30, 361, 5, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
484
485 SET_TIME( &T1, 1969,00,00, 00,00,00, 30, 360, 0, -120, 0);
486 CHECK_NZ(RTTimeLocalNormalize(&T1));
487 CHECK_TIME_LOCAL(&T1, 1969,12,26, 02,00,00, 30, 360, 4, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
488
489 SET_TIME( &T1, 1969,12,25, 00,00,00, 12, 0, 0, 15, 0);
490 CHECK_NZ(RTTimeLocalNormalize(&T1));
491 CHECK_TIME_LOCAL(&T1, 1969,12,24, 23,45,00, 12, 358, 2, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
492
493 SET_TIME( &T1, 1969,12,24, 00,00,00, 16, 0, 0, -15, 0);
494 CHECK_NZ(RTTimeLocalNormalize(&T1));
495 CHECK_TIME_LOCAL(&T1, 1969,12,24, 00,15,00, 16, 358, 2, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
496
497 /* outside the year table range */
498 SET_TIME( &T1, 1200,01,30, 00,00,00, 2, 0, 0, -720, 0);
499 CHECK_NZ(RTTimeLocalNormalize(&T1));
500 CHECK_TIME_LOCAL(&T1, 1200,01,30, 12,00,00, 2, 30, 6, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_LEAP_YEAR);
501
502 SET_TIME( &T1, 2555,11,29, 00,00,00, 2, 0, 0, -480, 0);
503 CHECK_NZ(RTTimeLocalNormalize(&T1));
504 CHECK_TIME_LOCAL(&T1, 2555,11,29, 8,00,00, 2, 333, 5, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
505
506 SET_TIME( &T1, 2555,00,00, 00,00,00, 3, 333, 0, 60, 0);
507 CHECK_NZ(RTTimeLocalNormalize(&T1));
508 CHECK_TIME_LOCAL(&T1, 2555,11,28, 23,00,00, 3, 332, 4, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
509
510 /* time overflow */
511 SET_TIME( &T1, 1969,12,30, 255,255,255, UINT32_MAX, 364, 0, 60, 0);
512 CHECK_NZ(RTTimeLocalNormalize(&T1));
513 CHECK_TIME_LOCAL(&T1, 1970,01, 9, 18,19,19,294967295, 9, 4, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
514
515 /* date overflow */
516 SET_TIME( &T1, 2007,11,36, 02,15,23, 1, 0, 0, 60, 0);
517 CHECK_NZ(RTTimeLocalNormalize(&T1));
518 CHECK_TIME_LOCAL(&T1, 2007,12,06, 01,15,23, 1, 340, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
519
520 SET_TIME( &T1, 2007,10,67, 02,15,23, 1, 0, 0, 60, 0);
521 CHECK_NZ(RTTimeLocalNormalize(&T1));
522 CHECK_TIME_LOCAL(&T1, 2007,12,06, 01,15,23, 1, 340, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
523
524 SET_TIME( &T1, 2007,10,98, 02,15,23, 1, 0, 0, 60, 0);
525 CHECK_NZ(RTTimeLocalNormalize(&T1));
526 CHECK_TIME_LOCAL(&T1, 2008,01,06, 01,15,23, 1, 6, 6, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_LEAP_YEAR);
527
528 SET_TIME( &T1, 2006,24,06, 02,15,23, 1, 0, 0, 60, 0);
529 CHECK_NZ(RTTimeLocalNormalize(&T1));
530 CHECK_TIME_LOCAL(&T1, 2007,12,06, 01,15,23, 1, 340, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
531
532 SET_TIME( &T1, 2003,60,37, 02,15,23, 1, 0, 0, -60, 0);
533 CHECK_NZ(RTTimeLocalNormalize(&T1));
534 CHECK_TIME_LOCAL(&T1, 2008,01,06, 03,15,23, 1, 6, 6, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_LEAP_YEAR);
535
536 SET_TIME( &T1, 2003,00,00, 02,15,23, 1,1801, 0, -60, 0);
537 CHECK_NZ(RTTimeLocalNormalize(&T1));
538 CHECK_TIME_LOCAL(&T1, 2007,12,06, 03,15,23, 1, 340, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
539
540 /*
541 * Test UTC and local time explode/implode round trips every 29 minutes for 3 years.
542 * Relies heavily on correct behavior of RTTimeNormalize and does limited sanity checking.
543 */
544 RTTestSub(hTest, "Wraparound 3 year (UTC+local), silent");
545 RTTimeSpecSetNano(&Ts1, INT64_C(1420070400000000000));
546 RTTIME Tcheck;
547 memset(&Tcheck, 0, sizeof(Tcheck));
548 Tcheck.i32Year = 2015;
549 Tcheck.u16YearDay = 1;
550 CHECK_NZ(RTTimeNormalize(&Tcheck));
551 while (Tcheck.i32Year <= 2017)
552 {
553 if (RTTimeIsLeapYear(Tcheck.i32Year))
554 {
555 if (!(Tcheck.fFlags & RTTIME_FLAGS_LEAP_YEAR))
556 RTTestIFailed("FAILURE - %d is not marked as a leap year, line no. %d\n",
557 Tcheck.i32Year, __LINE__);
558 }
559 else
560 {
561 if (!(Tcheck.fFlags & RTTIME_FLAGS_COMMON_YEAR))
562 RTTestIFailed("FAILURE - %d is not marked as a common year, line no. %d\n",
563 Tcheck.i32Year, __LINE__);
564 }
565
566 CHECK_NZ(RTTimeExplode(&T1, &Ts1));
567 CHECK_NZ(RTTimeImplode(&Ts2, &T1));
568 if (!RTTimeSpecIsEqual(&Ts2, &Ts1))
569 RTTestIFailed("FAILURE - %RI64 != %RI64, line no. %d\n",
570 RTTimeSpecGetNano(&Ts2), RTTimeSpecGetNano(&Ts1), __LINE__);
571 CHECK_TIME_SILENT(&T1, Tcheck.i32Year, Tcheck.u8Month, Tcheck.u8MonthDay, Tcheck.u8Hour, Tcheck.u8Minute, Tcheck.u8Second, Tcheck.u32Nanosecond, Tcheck.u16YearDay, Tcheck.u8WeekDay, Tcheck.offUTC, Tcheck.fFlags);
572
573 CHECK_NZ(RTTimeLocalExplode(&T1, &Ts1));
574 CHECK_NZ(RTTimeImplode(&Ts2, &T1));
575 if (!RTTimeSpecIsEqual(&Ts2, &Ts1))
576 RTTestIFailed("FAILURE - %RI64 != %RI64, line no. %d\n",
577 RTTimeSpecGetNano(&Ts2), RTTimeSpecGetNano(&Ts1), __LINE__);
578 CHECK_TIME_LOCAL_SILENT(&T1, Tcheck.i32Year, Tcheck.u8Month, Tcheck.u8MonthDay, Tcheck.u8Hour, Tcheck.u8Minute, Tcheck.u8Second, Tcheck.u32Nanosecond, Tcheck.u16YearDay, Tcheck.u8WeekDay, Tcheck.offUTC, Tcheck.fFlags);
579
580 RTTimeSpecAddNano(&Ts1, 29 * RT_NS_1MIN);
581 Tcheck.u8Minute += 29;
582 CHECK_NZ(RTTimeNormalize(&Tcheck));
583 }
584
585 /*
586 * Conversions.
587 */
588#define CHECK_NSEC(Ts1, T2) \
589 do { \
590 RTTIMESPEC TsTmp; \
591 RTTESTI_CHECK_MSG( RTTimeSpecGetNano(&(Ts1)) == RTTimeSpecGetNano(RTTimeImplode(&TsTmp, &(T2))), \
592 ("line %d: %RI64, %RI64\n", __LINE__, \
593 RTTimeSpecGetNano(&(Ts1)), RTTimeSpecGetNano(RTTimeImplode(&TsTmp, &(T2)))) ); \
594 } while (0)
595 RTTestSub(hTest, "Conversions, positive");
596 SET_TIME(&T1, 1980,01,01, 00,00,00, 0, 1, 1, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_LEAP_YEAR);
597 RTTESTI_CHECK(RTTimeSpecSetDosSeconds(&Ts2, 0) == &Ts2);
598 RTTESTI_CHECK(RTTimeSpecGetDosSeconds(&Ts2) == 0);
599 CHECK_NSEC(Ts2, T1);
600
601 SET_TIME(&T1, 1980,01,01, 00,00,00, 0, 1, 1, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_LEAP_YEAR);
602 RTTESTI_CHECK(RTTimeSpecSetNtTime(&Ts2, INT64_C(119600064000000000)) == &Ts2);
603 RTTESTI_CHECK(RTTimeSpecGetNtTime(&Ts2) == INT64_C(119600064000000000));
604 CHECK_NSEC(Ts2, T1);
605
606 SET_TIME(&T1, 1970,01,01, 00,00,01, 0, 1, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
607 RTTESTI_CHECK(RTTimeSpecSetSeconds(&Ts2, 1) == &Ts2);
608 RTTESTI_CHECK(RTTimeSpecGetSeconds(&Ts2) == 1);
609 CHECK_NSEC(Ts2, T1);
610
611 SET_TIME(&T1, 1970,01,01, 00,00,01, 0, 1, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
612 RTTESTI_CHECK(RTTimeSpecSetMilli(&Ts2, 1000) == &Ts2);
613 RTTESTI_CHECK(RTTimeSpecGetMilli(&Ts2) == 1000);
614 CHECK_NSEC(Ts2, T1);
615
616 SET_TIME(&T1, 1970,01,01, 00,00,01, 0, 1, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
617 RTTESTI_CHECK(RTTimeSpecSetMicro(&Ts2, 1000000) == &Ts2);
618 RTTESTI_CHECK(RTTimeSpecGetMicro(&Ts2) == 1000000);
619 CHECK_NSEC(Ts2, T1);
620
621 SET_TIME(&T1, 1970,01,01, 00,00,01, 0, 1, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
622 RTTESTI_CHECK(RTTimeSpecSetNano(&Ts2, 1000000000) == &Ts2);
623 RTTESTI_CHECK(RTTimeSpecGetNano(&Ts2) == 1000000000);
624 CHECK_NSEC(Ts2, T1);
625
626#ifdef RTTIME_INCL_TIMEVAL
627 SET_TIME(&T1, 1970,01,01, 00,00,01, 5000, 1, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
628 Tv1.tv_sec = 1;
629 Tv1.tv_usec = 5;
630 RTTESTI_CHECK(RTTimeSpecSetTimeval(&Ts2, &Tv1) == &Ts2);
631 RTTESTI_CHECK(RTTimeSpecGetMicro(&Ts2) == 1000005);
632 CHECK_NSEC(Ts2, T1);
633 RTTESTI_CHECK(RTTimeSpecGetTimeval(&Ts2, &Tv2) == &Tv2);
634 RTTESTI_CHECK(Tv1.tv_sec == Tv2.tv_sec); RTTESTI_CHECK(Tv1.tv_usec == Tv2.tv_usec);
635#endif
636
637#ifdef RTTIME_INCL_TIMESPEC
638 SET_TIME(&T1, 1970,01,01, 00,00,01, 5, 1, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
639 Tsp1.tv_sec = 1;
640 Tsp1.tv_nsec = 5;
641 RTTESTI_CHECK(RTTimeSpecSetTimespec(&Ts2, &Tsp1) == &Ts2);
642 RTTESTI_CHECK(RTTimeSpecGetNano(&Ts2) == 1000000005);
643 CHECK_NSEC(Ts2, T1);
644 RTTESTI_CHECK(RTTimeSpecGetTimespec(&Ts2, &Tsp2) == &Tsp2);
645 RTTESTI_CHECK(Tsp1.tv_sec == Tsp2.tv_sec); RTTESTI_CHECK(Tsp1.tv_nsec == Tsp2.tv_nsec);
646#endif
647
648
649 RTTestSub(hTest, "Conversions, negative");
650
651#ifdef RTTIME_INCL_TIMEVAL
652 SET_TIME(&T1, 1969,12,31, 23,59,58,999995000, 365, 2, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
653 Tv1.tv_sec = -2;
654 Tv1.tv_usec = 999995;
655 RTTESTI_CHECK(RTTimeSpecSetTimeval(&Ts2, &Tv1) == &Ts2);
656 RTTESTI_CHECK_MSG(RTTimeSpecGetMicro(&Ts2) == -1000005, ("%RI64\n", RTTimeSpecGetMicro(&Ts2)));
657 CHECK_NSEC(Ts2, T1);
658 RTTESTI_CHECK(RTTimeSpecGetTimeval(&Ts2, &Tv2) == &Tv2);
659 RTTESTI_CHECK(Tv1.tv_sec == Tv2.tv_sec); RTTESTI_CHECK(Tv1.tv_usec == Tv2.tv_usec);
660#endif
661
662#ifdef RTTIME_INCL_TIMESPEC
663 SET_TIME(&T1, 1969,12,31, 23,59,58,999999995, 365, 2, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
664 Tsp1.tv_sec = -2;
665 Tsp1.tv_nsec = 999999995;
666 RTTESTI_CHECK(RTTimeSpecSetTimespec(&Ts2, &Tsp1) == &Ts2);
667 RTTESTI_CHECK_MSG(RTTimeSpecGetNano(&Ts2) == -1000000005, ("%RI64\n", RTTimeSpecGetMicro(&Ts2)));
668 CHECK_NSEC(Ts2, T1);
669 RTTESTI_CHECK(RTTimeSpecGetTimespec(&Ts2, &Tsp2) == &Tsp2);
670 RTTESTI_CHECK(Tsp1.tv_sec == Tsp2.tv_sec); RTTESTI_CHECK(Tsp1.tv_nsec == Tsp2.tv_nsec);
671#endif
672
673 /*
674 * Test some string formatting too, while we're here...
675 */
676 RTTestSub(hTest, "Formatting");
677 char szValue[256];
678#define RTTESTI_CHECK_FMT(a_FmtCall, a_szExpect) \
679 do { \
680 ssize_t cchResult = a_FmtCall; \
681 if (cchResult != sizeof(a_szExpect) - 1 || strcmp(szValue, a_szExpect) != 0) \
682 RTTestFailed(hTest, "Got %s (%zd bytes) expected %s (%zu bytes); line " RT_XSTR(__LINE__), \
683 szValue, cchResult, a_szExpect, sizeof(a_szExpect) - 1); \
684 } while (0)
685#define RTTESTI_CHECK_FROM(a_FromCall) \
686 do { \
687 RTRandBytes(&T2, sizeof(T2)); \
688 PRTTIME pResult = a_FromCall; \
689 if (!pResult) \
690 RTTestFailed(hTest, "%s failed on line " RT_XSTR(__LINE__), #a_FromCall); \
691 else if (memcmp(&T1, &T2, sizeof(T2)) != 0) \
692 RTTestFailed(hTest, "%s produced incorrect result on line " RT_XSTR(__LINE__)": %s", #a_FromCall, ToString(&T2)); \
693 } while (0)
694 SET_TIME(&T1, 1969,12,31, 23,59,58,999995000, 365, 2, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
695 RTTESTI_CHECK_FMT(RTTimeToRfc2822(&T1, szValue, sizeof(szValue), 0), "Wed, 31 Dec 1969 23:59:58 -0000");
696 RTTESTI_CHECK_FMT(RTTimeToRfc2822(&T1, szValue, sizeof(szValue), RTTIME_RFC2822_F_GMT), "Wed, 31 Dec 1969 23:59:58 GMT");
697 RTTESTI_CHECK_FMT(RTTimeToStringEx(&T1, szValue, sizeof(szValue), 0), "1969-12-31T23:59:58Z");
698 RTTESTI_CHECK_FMT(RTTimeToStringEx(&T1, szValue, sizeof(szValue), 1), "1969-12-31T23:59:58.9Z");
699 RTTESTI_CHECK_FMT(RTTimeToStringEx(&T1, szValue, sizeof(szValue), 5), "1969-12-31T23:59:58.99999Z");
700 RTTESTI_CHECK_FMT(RTTimeToStringEx(&T1, szValue, sizeof(szValue), 9), "1969-12-31T23:59:58.999995000Z");
701 RTTESTI_CHECK_FROM(RTTimeFromString(&T2, "1969-12-31T23:59:58.999995000Z"));
702 RTTESTI_CHECK_FROM(RTTimeFromRfc2822(&T2, "Wed, 31 Dec 1969 23:59:58.999995 GMT"));
703 RTTESTI_CHECK_FROM(RTTimeFromRfc2822(&T2, "Wed, 31 Dec 69 23:59:58.999995 GMT"));
704 RTTESTI_CHECK_FROM(RTTimeFromRfc2822(&T2, "31 Dec 69 23:59:58.999995 GMT"));
705 RTTESTI_CHECK_FROM(RTTimeFromRfc2822(&T2, "31 Dec 1969 23:59:58.999995 GMT"));
706 RTTESTI_CHECK_FROM(RTTimeFromRfc2822(&T2, "31 dec 1969 23:59:58.999995 GMT"));
707 RTTESTI_CHECK_FROM(RTTimeFromRfc2822(&T2, "wEd, 31 Dec 69 23:59:58.999995 UT"));
708
709 SET_TIME(&T1, 2018, 9, 6, 4, 9, 8, 0, 249, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
710 RTTESTI_CHECK_FMT(RTTimeToRfc2822(&T1, szValue, sizeof(szValue), 0), "Thu, 6 Sep 2018 04:09:08 -0000");
711 RTTESTI_CHECK_FMT(RTTimeToStringEx(&T1, szValue, sizeof(szValue), 0), "2018-09-06T04:09:08Z");
712 RTTESTI_CHECK_FROM(RTTimeFromString(&T2, "2018-09-06T04:09:08Z"));
713 RTTESTI_CHECK_FROM(RTTimeFromRfc2822(&T2, "Thu, 6 Sep 2018 04:09:08 -0000"));
714 RTTESTI_CHECK_FROM(RTTimeFromRfc2822(&T2, "Thu, 6 Sep 2018 04:09:08 GMT"));
715 RTTESTI_CHECK_FROM(RTTimeFromRfc2822(&T2, "Thu, 06 Sep 2018 04:09:08 GMT"));
716 RTTESTI_CHECK_FROM(RTTimeFromRfc2822(&T2, "Thu, 00006 Sep 2018 04:09:08 GMT"));
717 RTTESTI_CHECK_FROM(RTTimeFromRfc2822(&T2, " 00006 Sep 2018 04:09:08 GMT "));
718
719
720 /*
721 * Duration.
722 */
723 RTTestSub(hTest, "Duration Formatting");
724 static struct { int64_t cNanoSecs; uint8_t cFractionDigits; const char *pszExpect; } const s_aDuration[] =
725 {
726 { 0, 0, "PT0S" },
727 { 0, 9, "PT0S" },
728 { RT_NS_1WEEK*52 + RT_NS_1DAY*3 + RT_NS_1HOUR*11 + RT_NS_1MIN*29 + RT_NS_1SEC_64*42 + 123456789, 9,
729 "P52W3DT11H29M42.123456789S" },
730 { RT_NS_1WEEK*52 + RT_NS_1DAY*3 + RT_NS_1HOUR*11 + RT_NS_1MIN*29 + RT_NS_1SEC_64*42 + 123456789, 0,
731 "P52W3DT11H29M42S" },
732 { RT_NS_1WEEK*9999 + RT_NS_1SEC_64*22 + 905964245, 0,
733 "P9999WT0H0M22S" },
734 { RT_NS_1WEEK*9999 + RT_NS_1SEC_64*22 + 905964245, 6,
735 "P9999WT0H0M22.905964S" },
736 { -(int64_t)(RT_NS_1WEEK*9999 + RT_NS_1SEC_64*22 + 905964245), 7,
737 "-P9999WT0H0M22.9059642S" },
738 { -(int64_t)(RT_NS_1WEEK*9999 + RT_NS_1SEC_64*22 + 905964245), 7,
739 "-P9999WT0H0M22.9059642S" },
740 { RT_NS_1WEEK*1 + RT_NS_1DAY*1 + RT_NS_1HOUR*1 + RT_NS_1MIN*2 + RT_NS_1SEC_64*1 + 111111111, 9,
741 "P1W1DT1H2M1.111111111S" },
742 { 1, 9, "PT0.000000001S" },
743 { 1, 3, "PT0.000S" },
744 };
745 for (size_t i = 0; i < RT_ELEMENTS(s_aDuration); i++)
746 {
747 RTTIMESPEC TimeSpec;
748 RTTimeSpecSetNano(&TimeSpec, s_aDuration[i].cNanoSecs);
749 ssize_t cchRet = RTTimeFormatDurationEx(szValue, sizeof(szValue), &TimeSpec, s_aDuration[i].cFractionDigits);
750 if ( cchRet != (ssize_t)strlen(s_aDuration[i].pszExpect)
751 || memcmp(szValue, s_aDuration[i].pszExpect, cchRet + 1) != 0)
752 RTTestIFailed("RTTimeFormatDurationEx/#%u: cchRet=%zd\n"
753 " szValue: '%s', length %zu\n"
754 " expected: '%s', length %zu",
755 i, cchRet, szValue, strlen(szValue), s_aDuration[i].pszExpect, strlen(s_aDuration[i].pszExpect));
756 }
757
758
759 /*
760 * Check that RTTimeZoneGetCurrent works (not really timespec, but whatever).
761 */
762 RTTestSub(hTest, "RTTimeZoneGetCurrent");
763 szValue[0] = '\0';
764 RTTESTI_CHECK_RC(RTTimeZoneGetCurrent(szValue, sizeof(szValue)), VINF_SUCCESS);
765 RTTestPrintf(hTest, RTTESTLVL_ALWAYS, "TimeZone: %s", szValue);
766
767 /*
768 * Summary
769 */
770 return RTTestSummaryAndDestroy(hTest);
771}
772
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette