VirtualBox

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

Last change on this file since 96781 was 96622, checked in by vboxsync, 2 years ago

IPRT: Added RTTimeFormatDuration[Ex] for duration/interval formatting.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 39.5 KB
Line 
1/* $Id: tstRTTimeSpec.cpp 96622 2022-09-07 01:24:26Z vboxsync $ */
2/** @file
3 * IPRT - RTTimeSpec and PRTTIME tests.
4 */
5
6/*
7 * Copyright (C) 2006-2022 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 */
57char *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