VirtualBox

source: vbox/trunk/include/iprt/time.h@ 53399

Last change on this file since 53399 was 51770, checked in by vboxsync, 10 years ago

Merged in iprt++ dev branch.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 27.9 KB
Line 
1/** @file
2 * IPRT - Time.
3 */
4
5/*
6 * Copyright (C) 2006-2012 Oracle Corporation
7 *
8 * This file is part of VirtualBox Open Source Edition (OSE), as
9 * available from http://www.virtualbox.org. This file is free software;
10 * you can redistribute it and/or modify it under the terms of the GNU
11 * General Public License (GPL) as published by the Free Software
12 * Foundation, in version 2 as it comes in the "COPYING" file of the
13 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
14 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
15 *
16 * The contents of this file may alternatively be used under the terms
17 * of the Common Development and Distribution License Version 1.0
18 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
19 * VirtualBox OSE distribution, in which case the provisions of the
20 * CDDL are applicable instead of those of the GPL.
21 *
22 * You may elect to license modified versions of this file under the
23 * terms and conditions of either the GPL or the CDDL or both.
24 */
25
26#ifndef ___iprt_time_h
27#define ___iprt_time_h
28
29#include <iprt/cdefs.h>
30#include <iprt/types.h>
31
32RT_C_DECLS_BEGIN
33
34/** @defgroup grp_rt_time RTTime - Time
35 * @ingroup grp_rt
36 * @{
37 */
38
39/** Time Specification.
40 *
41 * Use the inline RTTimeSpecGet/Set to operate on structure this so we
42 * can easily change the representation if required later.
43 *
44 * The current representation is in nanoseconds relative to the unix epoch
45 * (1970-01-01 00:00:00 UTC). This gives us an approximate span from
46 * 1678 to 2262 without sacrificing the resolution offered by the various
47 * host OSes (BSD & LINUX 1ns, NT 100ns).
48 */
49typedef struct RTTIMESPEC
50{
51 /** Nanoseconds since epoch.
52 * The name is intentially too long to be comfortable to use because you should be
53 * using inline helpers! */
54 int64_t i64NanosecondsRelativeToUnixEpoch;
55} RTTIMESPEC;
56
57
58/** @name RTTIMESPEC methods
59 * @{ */
60
61/**
62 * Gets the time as nanoseconds relative to the unix epoch.
63 *
64 * @returns Nanoseconds relative to unix epoch.
65 * @param pTime The time spec to interpret.
66 */
67DECLINLINE(int64_t) RTTimeSpecGetNano(PCRTTIMESPEC pTime)
68{
69 return pTime->i64NanosecondsRelativeToUnixEpoch;
70}
71
72
73/**
74 * Sets the time give by nanoseconds relative to the unix epoch.
75 *
76 * @returns pTime.
77 * @param pTime The time spec to modify.
78 * @param i64Nano The new time in nanoseconds.
79 */
80DECLINLINE(PRTTIMESPEC) RTTimeSpecSetNano(PRTTIMESPEC pTime, int64_t i64Nano)
81{
82 pTime->i64NanosecondsRelativeToUnixEpoch = i64Nano;
83 return pTime;
84}
85
86
87/**
88 * Gets the time as microseconds relative to the unix epoch.
89 *
90 * @returns microseconds relative to unix epoch.
91 * @param pTime The time spec to interpret.
92 */
93DECLINLINE(int64_t) RTTimeSpecGetMicro(PCRTTIMESPEC pTime)
94{
95 return pTime->i64NanosecondsRelativeToUnixEpoch / 1000;
96}
97
98
99/**
100 * Sets the time given by microseconds relative to the unix epoch.
101 *
102 * @returns pTime.
103 * @param pTime The time spec to modify.
104 * @param i64Micro The new time in microsecond.
105 */
106DECLINLINE(PRTTIMESPEC) RTTimeSpecSetMicro(PRTTIMESPEC pTime, int64_t i64Micro)
107{
108 pTime->i64NanosecondsRelativeToUnixEpoch = i64Micro * 1000;
109 return pTime;
110}
111
112
113/**
114 * Gets the time as milliseconds relative to the unix epoch.
115 *
116 * @returns milliseconds relative to unix epoch.
117 * @param pTime The time spec to interpret.
118 */
119DECLINLINE(int64_t) RTTimeSpecGetMilli(PCRTTIMESPEC pTime)
120{
121 return pTime->i64NanosecondsRelativeToUnixEpoch / 1000000;
122}
123
124
125/**
126 * Sets the time given by milliseconds relative to the unix epoch.
127 *
128 * @returns pTime.
129 * @param pTime The time spec to modify.
130 * @param i64Milli The new time in milliseconds.
131 */
132DECLINLINE(PRTTIMESPEC) RTTimeSpecSetMilli(PRTTIMESPEC pTime, int64_t i64Milli)
133{
134 pTime->i64NanosecondsRelativeToUnixEpoch = i64Milli * 1000000;
135 return pTime;
136}
137
138
139/**
140 * Gets the time as seconds relative to the unix epoch.
141 *
142 * @returns seconds relative to unix epoch.
143 * @param pTime The time spec to interpret.
144 */
145DECLINLINE(int64_t) RTTimeSpecGetSeconds(PCRTTIMESPEC pTime)
146{
147 return pTime->i64NanosecondsRelativeToUnixEpoch / 1000000000;
148}
149
150
151/**
152 * Sets the time given by seconds relative to the unix epoch.
153 *
154 * @returns pTime.
155 * @param pTime The time spec to modify.
156 * @param i64Seconds The new time in seconds.
157 */
158DECLINLINE(PRTTIMESPEC) RTTimeSpecSetSeconds(PRTTIMESPEC pTime, int64_t i64Seconds)
159{
160 pTime->i64NanosecondsRelativeToUnixEpoch = i64Seconds * 1000000000;
161 return pTime;
162}
163
164
165/**
166 * Makes the time spec absolute like abs() does (i.e. a positive value).
167 *
168 * @returns pTime.
169 * @param pTime The time spec to modify.
170 */
171DECLINLINE(PRTTIMESPEC) RTTimeSpecAbsolute(PRTTIMESPEC pTime)
172{
173 if (pTime->i64NanosecondsRelativeToUnixEpoch < 0)
174 pTime->i64NanosecondsRelativeToUnixEpoch = -pTime->i64NanosecondsRelativeToUnixEpoch;
175 return pTime;
176}
177
178
179/**
180 * Negates the time.
181 *
182 * @returns pTime.
183 * @param pTime The time spec to modify.
184 */
185DECLINLINE(PRTTIMESPEC) RTTimeSpecNegate(PRTTIMESPEC pTime)
186{
187 pTime->i64NanosecondsRelativeToUnixEpoch = -pTime->i64NanosecondsRelativeToUnixEpoch;
188 return pTime;
189}
190
191
192/**
193 * Adds a time period to the time.
194 *
195 * @returns pTime.
196 * @param pTime The time spec to modify.
197 * @param pTimeAdd The time spec to add to pTime.
198 */
199DECLINLINE(PRTTIMESPEC) RTTimeSpecAdd(PRTTIMESPEC pTime, PCRTTIMESPEC pTimeAdd)
200{
201 pTime->i64NanosecondsRelativeToUnixEpoch += pTimeAdd->i64NanosecondsRelativeToUnixEpoch;
202 return pTime;
203}
204
205
206/**
207 * Adds a time period give as nanoseconds from the time.
208 *
209 * @returns pTime.
210 * @param pTime The time spec to modify.
211 * @param i64Nano The time period in nanoseconds.
212 */
213DECLINLINE(PRTTIMESPEC) RTTimeSpecAddNano(PRTTIMESPEC pTime, int64_t i64Nano)
214{
215 pTime->i64NanosecondsRelativeToUnixEpoch += i64Nano;
216 return pTime;
217}
218
219
220/**
221 * Adds a time period give as microseconds from the time.
222 *
223 * @returns pTime.
224 * @param pTime The time spec to modify.
225 * @param i64Micro The time period in microseconds.
226 */
227DECLINLINE(PRTTIMESPEC) RTTimeSpecAddMicro(PRTTIMESPEC pTime, int64_t i64Micro)
228{
229 pTime->i64NanosecondsRelativeToUnixEpoch += i64Micro * 1000;
230 return pTime;
231}
232
233
234/**
235 * Adds a time period give as milliseconds from the time.
236 *
237 * @returns pTime.
238 * @param pTime The time spec to modify.
239 * @param i64Milli The time period in milliseconds.
240 */
241DECLINLINE(PRTTIMESPEC) RTTimeSpecAddMilli(PRTTIMESPEC pTime, int64_t i64Milli)
242{
243 pTime->i64NanosecondsRelativeToUnixEpoch += i64Milli * 1000000;
244 return pTime;
245}
246
247
248/**
249 * Adds a time period give as seconds from the time.
250 *
251 * @returns pTime.
252 * @param pTime The time spec to modify.
253 * @param i64Seconds The time period in seconds.
254 */
255DECLINLINE(PRTTIMESPEC) RTTimeSpecAddSeconds(PRTTIMESPEC pTime, int64_t i64Seconds)
256{
257 pTime->i64NanosecondsRelativeToUnixEpoch += i64Seconds * 1000000000;
258 return pTime;
259}
260
261
262/**
263 * Subtracts a time period from the time.
264 *
265 * @returns pTime.
266 * @param pTime The time spec to modify.
267 * @param pTimeSub The time spec to subtract from pTime.
268 */
269DECLINLINE(PRTTIMESPEC) RTTimeSpecSub(PRTTIMESPEC pTime, PCRTTIMESPEC pTimeSub)
270{
271 pTime->i64NanosecondsRelativeToUnixEpoch -= pTimeSub->i64NanosecondsRelativeToUnixEpoch;
272 return pTime;
273}
274
275
276/**
277 * Subtracts a time period give as nanoseconds from the time.
278 *
279 * @returns pTime.
280 * @param pTime The time spec to modify.
281 * @param i64Nano The time period in nanoseconds.
282 */
283DECLINLINE(PRTTIMESPEC) RTTimeSpecSubNano(PRTTIMESPEC pTime, int64_t i64Nano)
284{
285 pTime->i64NanosecondsRelativeToUnixEpoch -= i64Nano;
286 return pTime;
287}
288
289
290/**
291 * Subtracts a time period give as microseconds from the time.
292 *
293 * @returns pTime.
294 * @param pTime The time spec to modify.
295 * @param i64Micro The time period in microseconds.
296 */
297DECLINLINE(PRTTIMESPEC) RTTimeSpecSubMicro(PRTTIMESPEC pTime, int64_t i64Micro)
298{
299 pTime->i64NanosecondsRelativeToUnixEpoch -= i64Micro * 1000;
300 return pTime;
301}
302
303
304/**
305 * Subtracts a time period give as milliseconds from the time.
306 *
307 * @returns pTime.
308 * @param pTime The time spec to modify.
309 * @param i64Milli The time period in milliseconds.
310 */
311DECLINLINE(PRTTIMESPEC) RTTimeSpecSubMilli(PRTTIMESPEC pTime, int64_t i64Milli)
312{
313 pTime->i64NanosecondsRelativeToUnixEpoch -= i64Milli * 1000000;
314 return pTime;
315}
316
317
318/**
319 * Subtracts a time period give as seconds from the time.
320 *
321 * @returns pTime.
322 * @param pTime The time spec to modify.
323 * @param i64Seconds The time period in seconds.
324 */
325DECLINLINE(PRTTIMESPEC) RTTimeSpecSubSeconds(PRTTIMESPEC pTime, int64_t i64Seconds)
326{
327 pTime->i64NanosecondsRelativeToUnixEpoch -= i64Seconds * 100000000;
328 return pTime;
329}
330
331
332/* PORTME: Add struct timeval guard macro here. */
333#if defined(RTTIME_INCL_TIMEVAL) || defined(_STRUCT_TIMEVAL) || defined(_SYS__TIMEVAL_H_) || defined(_SYS_TIME_H) || defined(_TIMEVAL) || defined(_LINUX_TIME_H)
334/**
335 * Gets the time as POSIX timeval.
336 *
337 * @returns pTime.
338 * @param pTime The time spec to interpret.
339 * @param pTimeval Where to store the time as POSIX timeval.
340 */
341DECLINLINE(struct timeval *) RTTimeSpecGetTimeval(PCRTTIMESPEC pTime, struct timeval *pTimeval)
342{
343 int64_t i64 = RTTimeSpecGetMicro(pTime);
344 int32_t i32Micro = (int32_t)(i64 % 1000000);
345 i64 /= 1000000;
346 if (i32Micro < 0)
347 {
348 i32Micro += 1000000;
349 i64--;
350 }
351 pTimeval->tv_sec = (time_t)i64;
352 pTimeval->tv_usec = i32Micro;
353 return pTimeval;
354}
355
356/**
357 * Sets the time as POSIX timeval.
358 *
359 * @returns pTime.
360 * @param pTime The time spec to modify.
361 * @param pTimeval Pointer to the POSIX timeval struct with the new time.
362 */
363DECLINLINE(PRTTIMESPEC) RTTimeSpecSetTimeval(PRTTIMESPEC pTime, const struct timeval *pTimeval)
364{
365 return RTTimeSpecAddMicro(RTTimeSpecSetSeconds(pTime, pTimeval->tv_sec), pTimeval->tv_usec);
366}
367#endif /* various ways of detecting struct timeval */
368
369
370/* PORTME: Add struct timespec guard macro here. */
371#if defined(RTTIME_INCL_TIMESPEC) || defined(_STRUCT_TIMESPEC) || defined(_SYS__TIMESPEC_H_) || defined(TIMEVAL_TO_TIMESPEC) || defined(_TIMESPEC)
372/**
373 * Gets the time as POSIX timespec.
374 *
375 * @returns pTime.
376 * @param pTime The time spec to interpret.
377 * @param pTimespec Where to store the time as POSIX timespec.
378 */
379DECLINLINE(struct timespec *) RTTimeSpecGetTimespec(PCRTTIMESPEC pTime, struct timespec *pTimespec)
380{
381 int64_t i64 = RTTimeSpecGetNano(pTime);
382 int32_t i32Nano = (int32_t)(i64 % 1000000000);
383 i64 /= 1000000000;
384 if (i32Nano < 0)
385 {
386 i32Nano += 1000000000;
387 i64--;
388 }
389 pTimespec->tv_sec = (time_t)i64;
390 pTimespec->tv_nsec = i32Nano;
391 return pTimespec;
392}
393
394/**
395 * Sets the time as POSIX timespec.
396 *
397 * @returns pTime.
398 * @param pTime The time spec to modify.
399 * @param pTimespec Pointer to the POSIX timespec struct with the new time.
400 */
401DECLINLINE(PRTTIMESPEC) RTTimeSpecSetTimespec(PRTTIMESPEC pTime, const struct timespec *pTimespec)
402{
403 return RTTimeSpecAddNano(RTTimeSpecSetSeconds(pTime, pTimespec->tv_sec), pTimespec->tv_nsec);
404}
405#endif /* various ways of detecting struct timespec */
406
407
408
409/** The offset of the unix epoch and the base for NT time (in 100ns units).
410 * Nt time starts at 1601-01-01 00:00:00. */
411#define RTTIME_NT_TIME_OFFSET_UNIX (116444736000000000LL)
412
413
414/**
415 * Gets the time as NT time.
416 *
417 * @returns Nt time.
418 * @param pTime The time spec to interpret.
419 */
420DECLINLINE(uint64_t) RTTimeSpecGetNtTime(PCRTTIMESPEC pTime)
421{
422 return pTime->i64NanosecondsRelativeToUnixEpoch / 100
423 + RTTIME_NT_TIME_OFFSET_UNIX;
424}
425
426
427/**
428 * Sets the time given by Nt time.
429 *
430 * @returns pTime.
431 * @param pTime The time spec to modify.
432 * @param u64NtTime The new time in Nt time.
433 */
434DECLINLINE(PRTTIMESPEC) RTTimeSpecSetNtTime(PRTTIMESPEC pTime, uint64_t u64NtTime)
435{
436 pTime->i64NanosecondsRelativeToUnixEpoch =
437 ((int64_t)u64NtTime - RTTIME_NT_TIME_OFFSET_UNIX) * 100;
438 return pTime;
439}
440
441
442#ifdef _FILETIME_
443/**
444 * Gets the time as NT file time.
445 *
446 * @returns pFileTime.
447 * @param pTime The time spec to interpret.
448 * @param pFileTime Pointer to NT filetime structure.
449 */
450DECLINLINE(PFILETIME) RTTimeSpecGetNtFileTime(PCRTTIMESPEC pTime, PFILETIME pFileTime)
451{
452 *((uint64_t *)pFileTime) = RTTimeSpecGetNtTime(pTime);
453 return pFileTime;
454}
455
456/**
457 * Sets the time as NT file time.
458 *
459 * @returns pTime.
460 * @param pTime The time spec to modify.
461 * @param pFileTime Where to store the time as Nt file time.
462 */
463DECLINLINE(PRTTIMESPEC) RTTimeSpecSetNtFileTime(PRTTIMESPEC pTime, const FILETIME *pFileTime)
464{
465 return RTTimeSpecSetNtTime(pTime, *(const uint64_t *)pFileTime);
466}
467#endif
468
469
470/** The offset to the start of DOS time.
471 * DOS time starts 1980-01-01 00:00:00. */
472#define RTTIME_OFFSET_DOS_TIME (315532800000000000LL)
473
474
475/**
476 * Gets the time as seconds relative to the start of dos time.
477 *
478 * @returns seconds relative to the start of dos time.
479 * @param pTime The time spec to interpret.
480 */
481DECLINLINE(int64_t) RTTimeSpecGetDosSeconds(PCRTTIMESPEC pTime)
482{
483 return (pTime->i64NanosecondsRelativeToUnixEpoch - RTTIME_OFFSET_DOS_TIME)
484 / 1000000000;
485}
486
487
488/**
489 * Sets the time given by seconds relative to the start of dos time.
490 *
491 * @returns pTime.
492 * @param pTime The time spec to modify.
493 * @param i64Seconds The new time in seconds relative to the start of dos time.
494 */
495DECLINLINE(PRTTIMESPEC) RTTimeSpecSetDosSeconds(PRTTIMESPEC pTime, int64_t i64Seconds)
496{
497 pTime->i64NanosecondsRelativeToUnixEpoch = i64Seconds * 1000000000
498 + RTTIME_OFFSET_DOS_TIME;
499 return pTime;
500}
501
502
503/**
504 * Compare two time specs.
505 *
506 * @returns true they are equal.
507 * @returns false they are not equal.
508 * @param pTime1 The 1st time spec.
509 * @param pTime2 The 2nd time spec.
510 */
511DECLINLINE(bool) RTTimeSpecIsEqual(PCRTTIMESPEC pTime1, PCRTTIMESPEC pTime2)
512{
513 return pTime1->i64NanosecondsRelativeToUnixEpoch == pTime2->i64NanosecondsRelativeToUnixEpoch;
514}
515
516
517/**
518 * Compare two time specs.
519 *
520 * @returns 0 if equal, -1 if @a pLeft is smaller, 1 if @a pLeft is larger.
521 * @returns false they are not equal.
522 * @param pLeft The 1st time spec.
523 * @param pRight The 2nd time spec.
524 */
525DECLINLINE(int) RTTimeSpecCompare(PCRTTIMESPEC pLeft, PCRTTIMESPEC pRight)
526{
527 if (pLeft->i64NanosecondsRelativeToUnixEpoch == pRight->i64NanosecondsRelativeToUnixEpoch)
528 return 0;
529 return pLeft->i64NanosecondsRelativeToUnixEpoch < pRight->i64NanosecondsRelativeToUnixEpoch ? -1 : 1;
530}
531
532
533/**
534 * Converts a time spec to a ISO date string.
535 *
536 * @returns psz on success.
537 * @returns NULL on buffer underflow.
538 * @param pTime The time spec.
539 * @param psz Where to store the string.
540 * @param cb The size of the buffer.
541 */
542RTDECL(char *) RTTimeSpecToString(PCRTTIMESPEC pTime, char *psz, size_t cb);
543
544/**
545 * Attempts to convert an ISO date string to a time structure.
546 *
547 * We're a little forgiving with zero padding, unspecified parts, and leading
548 * and trailing spaces.
549 *
550 * @retval pTime on success,
551 * @retval NULL on failure.
552 * @param pTime The time spec.
553 * @param pszString The ISO date string to convert.
554 */
555RTDECL(PRTTIMESPEC) RTTimeSpecFromString(PRTTIMESPEC pTime, const char *pszString);
556
557/** @} */
558
559
560/**
561 * Exploded time.
562 */
563#pragma pack(1)
564typedef struct RTTIME
565{
566 /** The year number. */
567 int32_t i32Year;
568 /** The month of the year (1-12). January is 1. */
569 uint8_t u8Month;
570 /** The day of the week (0-6). Monday is 0. */
571 uint8_t u8WeekDay;
572 /** The day of the year (1-366). January the 1st is 1. */
573 uint16_t u16YearDay;
574 /** The day of the month (1-31). */
575 uint8_t u8MonthDay;
576 /** Hour of the day (0-23). */
577 uint8_t u8Hour;
578 /** The minute of the hour (0-59). */
579 uint8_t u8Minute;
580 /** The second of the minute (0-60).
581 * (u32Nanosecond / 1000000) */
582 uint8_t u8Second;
583 /** The nanoseconds of the second (0-999999999). */
584 uint32_t u32Nanosecond;
585 /** Flags, of the RTTIME_FLAGS_* \#defines. */
586 uint32_t fFlags;
587 /** UCT time offset in minutes (-840-840).
588 * @remarks The implementation of RTTimeLocal* isn't quite there yet, so this might not be 100% correct. */
589 int32_t offUTC;
590} RTTIME;
591#pragma pack()
592/** Pointer to a exploded time structure. */
593typedef RTTIME *PRTTIME;
594/** Pointer to a const exploded time structure. */
595typedef const RTTIME *PCRTTIME;
596
597/** @name RTTIME::fFlags values.
598 * @{ */
599/** Set if the time is UTC. If clear the time local time. */
600#define RTTIME_FLAGS_TYPE_MASK 3
601/** the time is UTC time. */
602#define RTTIME_FLAGS_TYPE_UTC 2
603/** The time is local time. */
604#define RTTIME_FLAGS_TYPE_LOCAL 3
605
606/** Set if the time is local and daylight saving time is in effect.
607 * Not bit is not valid if RTTIME_FLAGS_NO_DST_DATA is set. */
608#define RTTIME_FLAGS_DST RT_BIT(4)
609/** Set if the time is local and there is no data available on daylight saving time. */
610#define RTTIME_FLAGS_NO_DST_DATA RT_BIT(5)
611/** Set if the year is a leap year.
612 * This is mutual exclusiv with RTTIME_FLAGS_COMMON_YEAR. */
613#define RTTIME_FLAGS_LEAP_YEAR RT_BIT(6)
614/** Set if the year is a common year.
615 * This is mutual exclusiv with RTTIME_FLAGS_LEAP_YEAR. */
616#define RTTIME_FLAGS_COMMON_YEAR RT_BIT(7)
617/** The mask of valid flags. */
618#define RTTIME_FLAGS_MASK UINT32_C(0xff)
619/** @} */
620
621
622/**
623 * Gets the current system time (UTC).
624 *
625 * @returns pTime.
626 * @param pTime Where to store the time.
627 */
628RTDECL(PRTTIMESPEC) RTTimeNow(PRTTIMESPEC pTime);
629
630/**
631 * Sets the system time.
632 *
633 * @returns IPRT status code
634 * @param pTime The new system time (UTC).
635 *
636 * @remarks This will usually fail because changing the wall time is usually
637 * requires extra privileges.
638 */
639RTDECL(int) RTTimeSet(PCRTTIMESPEC pTime);
640
641/**
642 * Explodes a time spec (UTC).
643 *
644 * @returns pTime.
645 * @param pTime Where to store the exploded time.
646 * @param pTimeSpec The time spec to exploded.
647 */
648RTDECL(PRTTIME) RTTimeExplode(PRTTIME pTime, PCRTTIMESPEC pTimeSpec);
649
650/**
651 * Implodes exploded time to a time spec (UTC).
652 *
653 * @returns pTime on success.
654 * @returns NULL if the pTime data is invalid.
655 * @param pTimeSpec Where to store the imploded UTC time.
656 * If pTime specifies a time which outside the range, maximum or
657 * minimum values will be returned.
658 * @param pTime Pointer to the exploded time to implode.
659 * The fields u8Month, u8WeekDay and u8MonthDay are not used,
660 * and all the other fields are expected to be within their
661 * bounds. Use RTTimeNormalize() to calculate u16YearDay and
662 * normalize the ranges of the fields.
663 */
664RTDECL(PRTTIMESPEC) RTTimeImplode(PRTTIMESPEC pTimeSpec, PCRTTIME pTime);
665
666/**
667 * Normalizes the fields of a time structure.
668 *
669 * It is possible to calculate year-day from month/day and vice
670 * versa. If you adjust any of of these, make sure to zero the
671 * other so you make it clear which of the fields to use. If
672 * it's ambiguous, the year-day field is used (and you get
673 * assertions in debug builds).
674 *
675 * All the time fields and the year-day or month/day fields will
676 * be adjusted for overflows. (Since all fields are unsigned, there
677 * is no underflows.) It is possible to exploit this for simple
678 * date math, though the recommended way of doing that to implode
679 * the time into a timespec and do the math on that.
680 *
681 * @returns pTime on success.
682 * @returns NULL if the data is invalid.
683 *
684 * @param pTime The time structure to normalize.
685 *
686 * @remarks This function doesn't work with local time, only with UTC time.
687 */
688RTDECL(PRTTIME) RTTimeNormalize(PRTTIME pTime);
689
690/**
691 * Gets the current local system time.
692 *
693 * @returns pTime.
694 * @param pTime Where to store the local time.
695 */
696RTDECL(PRTTIMESPEC) RTTimeLocalNow(PRTTIMESPEC pTime);
697
698/**
699 * Gets the delta between UTC and local time.
700 *
701 * @code
702 * RTTIMESPEC LocalTime;
703 * RTTimeSpecAddNano(RTTimeNow(&LocalTime), RTTimeLocalDeltaNano());
704 * @endcode
705 *
706 * @returns Returns the nanosecond delta between UTC and local time.
707 */
708RTDECL(int64_t) RTTimeLocalDeltaNano(void);
709
710/**
711 * Explodes a time spec to the localized timezone.
712 *
713 * @returns pTime.
714 * @param pTime Where to store the exploded time.
715 * @param pTimeSpec The time spec to exploded (UTC).
716 */
717RTDECL(PRTTIME) RTTimeLocalExplode(PRTTIME pTime, PCRTTIMESPEC pTimeSpec);
718
719/**
720 * Normalizes the fields of a time structure containing local time.
721 *
722 * See RTTimeNormalize for details.
723 *
724 * @returns pTime on success.
725 * @returns NULL if the data is invalid.
726 * @param pTime The time structure to normalize.
727 */
728RTDECL(PRTTIME) RTTimeLocalNormalize(PRTTIME pTime);
729
730/**
731 * Converts a time spec to a ISO date string.
732 *
733 * @returns psz on success.
734 * @returns NULL on buffer underflow.
735 * @param pTime The time. Caller should've normalized this.
736 * @param psz Where to store the string.
737 * @param cb The size of the buffer.
738 */
739RTDECL(char *) RTTimeToString(PCRTTIME pTime, char *psz, size_t cb);
740
741/**
742 * Attempts to convert an ISO date string to a time structure.
743 *
744 * We're a little forgiving with zero padding, unspecified parts, and leading
745 * and trailing spaces.
746 *
747 * @retval pTime on success,
748 * @retval NULL on failure.
749 * @param pTime Where to store the time on success.
750 * @param pszString The ISO date string to convert.
751 */
752RTDECL(PRTTIME) RTTimeFromString(PRTTIME pTime, const char *pszString);
753
754/**
755 * Checks if a year is a leap year or not.
756 *
757 * @returns true if it's a leap year.
758 * @returns false if it's a common year.
759 * @param i32Year The year in question.
760 */
761RTDECL(bool) RTTimeIsLeapYear(int32_t i32Year);
762
763/**
764 * Gets the current nanosecond timestamp.
765 *
766 * @returns nanosecond timestamp.
767 */
768RTDECL(uint64_t) RTTimeNanoTS(void);
769
770/**
771 * Gets the current millisecond timestamp.
772 *
773 * @returns millisecond timestamp.
774 */
775RTDECL(uint64_t) RTTimeMilliTS(void);
776
777/**
778 * Debugging the time api.
779 *
780 * @returns the number of 1ns steps which has been applied by RTTimeNanoTS().
781 */
782RTDECL(uint32_t) RTTimeDbgSteps(void);
783
784/**
785 * Debugging the time api.
786 *
787 * @returns the number of times the TSC interval expired RTTimeNanoTS().
788 */
789RTDECL(uint32_t) RTTimeDbgExpired(void);
790
791/**
792 * Debugging the time api.
793 *
794 * @returns the number of bad previous values encountered by RTTimeNanoTS().
795 */
796RTDECL(uint32_t) RTTimeDbgBad(void);
797
798/**
799 * Debugging the time api.
800 *
801 * @returns the number of update races in RTTimeNanoTS().
802 */
803RTDECL(uint32_t) RTTimeDbgRaces(void);
804
805/** @name RTTimeNanoTS GIP worker functions, for TM.
806 * @{ */
807/** Pointer to a RTTIMENANOTSDATA structure. */
808typedef struct RTTIMENANOTSDATA *PRTTIMENANOTSDATA;
809
810/**
811 * Nanosecond timestamp data.
812 *
813 * This is used to keep track of statistics and callback so IPRT
814 * and TM (VirtualBox) can share code.
815 *
816 * @remark Keep this in sync with the assembly version in timesupA.asm.
817 */
818typedef struct RTTIMENANOTSDATA
819{
820 /** Where the previous timestamp is stored.
821 * This is maintained to ensure that time doesn't go backwards or anything. */
822 uint64_t volatile *pu64Prev;
823
824 /**
825 * Helper function that's used by the assembly routines when something goes bust.
826 *
827 * @param pData Pointer to this structure.
828 * @param u64NanoTS The calculated nano ts.
829 * @param u64DeltaPrev The delta relative to the previously returned timestamp.
830 * @param u64PrevNanoTS The previously returned timestamp (as it was read it).
831 */
832 DECLCALLBACKMEMBER(void, pfnBad)(PRTTIMENANOTSDATA pData, uint64_t u64NanoTS, uint64_t u64DeltaPrev, uint64_t u64PrevNanoTS);
833
834 /**
835 * Callback for when rediscovery is required.
836 *
837 * @returns Nanosecond timestamp.
838 * @param pData Pointer to this structure.
839 */
840 DECLCALLBACKMEMBER(uint64_t, pfnRediscover)(PRTTIMENANOTSDATA pData);
841
842 /** Just a dummy alignment member. */
843 void *pvDummy;
844
845 /** Number of 1ns steps because of overshooting the period. */
846 uint32_t c1nsSteps;
847 /** The number of times the interval expired (overflow). */
848 uint32_t cExpired;
849 /** Number of "bad" previous values. */
850 uint32_t cBadPrev;
851 /** The number of update races. */
852 uint32_t cUpdateRaces;
853} RTTIMENANOTSDATA;
854
855#ifndef IN_RING3
856/**
857 * The Ring-3 layout of the RTTIMENANOTSDATA structure.
858 */
859typedef struct RTTIMENANOTSDATAR3
860{
861 R3PTRTYPE(uint64_t volatile *) pu64Prev;
862 DECLR3CALLBACKMEMBER(void, pfnBad,(PRTTIMENANOTSDATA pData, uint64_t u64NanoTS, uint64_t u64DeltaPrev, uint64_t u64PrevNanoTS));
863 DECLR3CALLBACKMEMBER(uint64_t, pfnRediscover,(PRTTIMENANOTSDATA pData));
864 RTR3PTR pvDummy;
865 uint32_t c1nsSteps;
866 uint32_t cExpired;
867 uint32_t cBadPrev;
868 uint32_t cUpdateRaces;
869} RTTIMENANOTSDATAR3;
870#else
871typedef RTTIMENANOTSDATA RTTIMENANOTSDATAR3;
872#endif
873
874#ifndef IN_RING0
875/**
876 * The Ring-3 layout of the RTTIMENANOTSDATA structure.
877 */
878typedef struct RTTIMENANOTSDATAR0
879{
880 R0PTRTYPE(uint64_t volatile *) pu64Prev;
881 DECLR0CALLBACKMEMBER(void, pfnBad,(PRTTIMENANOTSDATA pData, uint64_t u64NanoTS, uint64_t u64DeltaPrev, uint64_t u64PrevNanoTS));
882 DECLR0CALLBACKMEMBER(uint64_t, pfnRediscover,(PRTTIMENANOTSDATA pData));
883 RTR0PTR pvDummy;
884 uint32_t c1nsSteps;
885 uint32_t cExpired;
886 uint32_t cBadPrev;
887 uint32_t cUpdateRaces;
888} RTTIMENANOTSDATAR0;
889#else
890typedef RTTIMENANOTSDATA RTTIMENANOTSDATAR0;
891#endif
892
893#ifndef IN_RC
894/**
895 * The RC layout of the RTTIMENANOTSDATA structure.
896 */
897typedef struct RTTIMENANOTSDATARC
898{
899 RCPTRTYPE(uint64_t volatile *) pu64Prev;
900 DECLRCCALLBACKMEMBER(void, pfnBad,(PRTTIMENANOTSDATA pData, uint64_t u64NanoTS, uint64_t u64DeltaPrev, uint64_t u64PrevNanoTS));
901 DECLRCCALLBACKMEMBER(uint64_t, pfnRediscover,(PRTTIMENANOTSDATA pData));
902 RCPTRTYPE(void *) pvDummy;
903 uint32_t c1nsSteps;
904 uint32_t cExpired;
905 uint32_t cBadPrev;
906 uint32_t cUpdateRaces;
907} RTTIMENANOTSDATARC;
908#else
909typedef RTTIMENANOTSDATA RTTIMENANOTSDATARC;
910#endif
911
912/** Internal RTTimeNanoTS worker (assembly). */
913typedef DECLCALLBACK(uint64_t) FNTIMENANOTSINTERNAL(PRTTIMENANOTSDATA pData);
914/** Pointer to an internal RTTimeNanoTS worker (assembly). */
915typedef FNTIMENANOTSINTERNAL *PFNTIMENANOTSINTERNAL;
916
917RTDECL(uint64_t) RTTimeNanoTSLegacySync(PRTTIMENANOTSDATA pData);
918RTDECL(uint64_t) RTTimeNanoTSLegacyAsync(PRTTIMENANOTSDATA pData);
919RTDECL(uint64_t) RTTimeNanoTSLFenceSync(PRTTIMENANOTSDATA pData);
920RTDECL(uint64_t) RTTimeNanoTSLFenceAsync(PRTTIMENANOTSDATA pData);
921/** @} */
922
923
924/**
925 * Gets the current nanosecond timestamp.
926 *
927 * This differs from RTTimeNanoTS in that it will use system APIs and not do any
928 * resolution or performance optimizations.
929 *
930 * @returns nanosecond timestamp.
931 */
932RTDECL(uint64_t) RTTimeSystemNanoTS(void);
933
934/**
935 * Gets the current millisecond timestamp.
936 *
937 * This differs from RTTimeNanoTS in that it will use system APIs and not do any
938 * resolution or performance optimizations.
939 *
940 * @returns millisecond timestamp.
941 */
942RTDECL(uint64_t) RTTimeSystemMilliTS(void);
943
944/**
945 * Get the nanosecond timestamp relative to program startup.
946 *
947 * @returns Timestamp relative to program startup.
948 */
949RTDECL(uint64_t) RTTimeProgramNanoTS(void);
950
951/**
952 * Get the microsecond timestamp relative to program startup.
953 *
954 * @returns Timestamp relative to program startup.
955 */
956RTDECL(uint64_t) RTTimeProgramMicroTS(void);
957
958/**
959 * Get the millisecond timestamp relative to program startup.
960 *
961 * @returns Timestamp relative to program startup.
962 */
963RTDECL(uint64_t) RTTimeProgramMilliTS(void);
964
965/**
966 * Get the second timestamp relative to program startup.
967 *
968 * @returns Timestamp relative to program startup.
969 */
970RTDECL(uint32_t) RTTimeProgramSecTS(void);
971
972/**
973 * Get the RTTimeNanoTS() of when the program started.
974 *
975 * @returns Program startup timestamp.
976 */
977RTDECL(uint64_t) RTTimeProgramStartNanoTS(void);
978
979/** @} */
980
981RT_C_DECLS_END
982
983#endif
984
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