1 /** 2 * collectd - src/daemon/utils_time.h 3 * Copyright (C) 2010-2015 Florian octo Forster 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the "Software"), 7 * to deal in the Software without restriction, including without limitation 8 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 * and/or sell copies of the Software, and to permit persons to whom the 10 * Software is furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice shall be included in 13 * all copies or substantial portions of the Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21 * DEALINGS IN THE SOFTWARE. 22 * 23 * Authors: 24 * Florian octo Forster <octo at collectd.org> 25 **/ 26 27 #ifndef UTILS_TIME_H 28 #define UTILS_TIME_H 1 29 30 #include "collectd.h" 31 32 #ifdef TESTING_H 33 /* cdtime_mock is the time returned by cdtime() when build with 34 * -DMOCK_TIME */ 35 extern cdtime_t cdtime_mock; 36 #endif 37 38 /* 39 * "cdtime_t" is a 64bit unsigned integer. The time is stored at a 2^-30 second 40 * resolution, i.e. the most significant 34 bit are used to store the time in 41 * seconds, the least significant bits store the sub-second part in something 42 * very close to nanoseconds. *The* big advantage of storing time in this 43 * manner is that comparing times and calculating differences is as simple as 44 * it is with "time_t", i.e. a simple integer comparison / subtraction works. 45 */ 46 /* 47 * cdtime_t is defined in "collectd.h" */ 48 /* typedef uint64_t cdtime_t; */ 49 50 /* 2^30 = 1073741824 */ 51 #define TIME_T_TO_CDTIME_T_STATIC(t) (((cdtime_t)(t)) << 30) 52 #define TIME_T_TO_CDTIME_T(t) \ 53 (cdtime_t) { TIME_T_TO_CDTIME_T_STATIC(t) } 54 55 #define MS_TO_CDTIME_T(ms) \ 56 (cdtime_t) { \ 57 ((((cdtime_t)(ms)) / 1000) << 30) | \ 58 ((((((cdtime_t)(ms)) % 1000) << 30) + 500) / 1000) \ 59 } 60 #define US_TO_CDTIME_T(us) \ 61 (cdtime_t) { \ 62 ((((cdtime_t)(us)) / 1000000) << 30) | \ 63 ((((((cdtime_t)(us)) % 1000000) << 30) + 500000) / 1000000) \ 64 } 65 #define NS_TO_CDTIME_T(ns) \ 66 (cdtime_t) { \ 67 ((((cdtime_t)(ns)) / 1000000000) << 30) | \ 68 ((((((cdtime_t)(ns)) % 1000000000) << 30) + 500000000) / 1000000000) \ 69 } 70 71 #define CDTIME_T_TO_TIME_T(t) \ 72 (time_t) { (time_t)(((t) + (1 << 29)) >> 30) } 73 #define CDTIME_T_TO_MS(t) \ 74 (uint64_t) { \ 75 (uint64_t)((((t) >> 30) * 1000) + \ 76 ((((t)&0x3fffffff) * 1000 + (1 << 29)) >> 30)) \ 77 } 78 #define CDTIME_T_TO_US(t) \ 79 (uint64_t) { \ 80 (uint64_t)((((t) >> 30) * 1000000) + \ 81 ((((t)&0x3fffffff) * 1000000 + (1 << 29)) >> 30)) \ 82 } 83 #define CDTIME_T_TO_NS(t) \ 84 (uint64_t) { \ 85 (uint64_t)((((t) >> 30) * 1000000000) + \ 86 ((((t)&0x3fffffff) * 1000000000 + (1 << 29)) >> 30)) \ 87 } 88 89 #define CDTIME_T_TO_DOUBLE(t) \ 90 (double) { ((double)(t)) / 1073741824.0 } 91 #define DOUBLE_TO_CDTIME_T_STATIC(d) ((cdtime_t)((d)*1073741824.0)) 92 #define DOUBLE_TO_CDTIME_T(d) \ 93 (cdtime_t) { DOUBLE_TO_CDTIME_T_STATIC(d) } 94 95 #define CDTIME_T_TO_TIMEVAL(t) \ 96 (struct timeval) { \ 97 .tv_sec = (time_t)((t) >> 30), \ 98 .tv_usec = (suseconds_t)((((t)&0x3fffffff) * 1000000 + (1 << 29)) >> 30), \ 99 } 100 #define TIMEVAL_TO_CDTIME_T(tv) \ 101 US_TO_CDTIME_T(1000000 * (tv)->tv_sec + (tv)->tv_usec) 102 103 #define CDTIME_T_TO_TIMESPEC(t) \ 104 (struct timespec) { \ 105 .tv_sec = (time_t)((t) >> 30), \ 106 .tv_nsec = (long)((((t)&0x3fffffff) * 1000000000 + (1 << 29)) >> 30), \ 107 } 108 #define TIMESPEC_TO_CDTIME_T(ts) \ 109 NS_TO_CDTIME_T(1000000000ULL * (ts)->tv_sec + (ts)->tv_nsec) 110 111 cdtime_t cdtime(void); 112 113 #define RFC3339_SIZE 26 /* 2006-01-02T15:04:05+00:00 */ 114 #define RFC3339NANO_SIZE 36 /* 2006-01-02T15:04:05.999999999+00:00 */ 115 116 /* rfc3339 formats a cdtime_t time as UTC in RFC 3339 zulu format with second 117 * precision, e.g., "2006-01-02T15:04:05Z". */ 118 int rfc3339(char *buffer, size_t buffer_size, cdtime_t t); 119 120 /* rfc3339nano formats a cdtime_t as UTC time in RFC 3339 zulu format with 121 * nanosecond precision, e.g., "2006-01-02T15:04:05.999999999Z". */ 122 int rfc3339nano(char *buffer, size_t buffer_size, cdtime_t t); 123 124 /* rfc3339 formats a cdtime_t time as local in RFC 3339 format with second 125 * precision, e.g., "2006-01-02T15:04:05+00:00". */ 126 int rfc3339_local(char *buffer, size_t buffer_size, cdtime_t t); 127 128 /* rfc3339nano formats a cdtime_t time as local in RFC 3339 format with 129 * nanosecond precision, e.g., "2006-01-02T15:04:05.999999999+00:00". */ 130 int rfc3339nano_local(char *buffer, size_t buffer_size, cdtime_t t); 131 132 #endif /* UTILS_TIME_H */ 133