00001 /* 00002 * Copyright (C) 2004-2009, 2012, 2014, 2015 Internet Systems Consortium, Inc. ("ISC") 00003 * Copyright (C) 1998-2001 Internet Software Consortium. 00004 * 00005 * Permission to use, copy, modify, and/or distribute this software for any 00006 * purpose with or without fee is hereby granted, provided that the above 00007 * copyright notice and this permission notice appear in all copies. 00008 * 00009 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 00010 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 00011 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 00012 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 00013 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 00014 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 00015 * PERFORMANCE OF THIS SOFTWARE. 00016 */ 00017 00018 /* $Id: time.h,v 1.40 2009/01/05 23:47:54 tbox Exp $ */ 00019 00020 #ifndef ISC_TIME_H 00021 #define ISC_TIME_H 1 00022 00023 /*! \file */ 00024 00025 #include <isc/lang.h> 00026 #include <isc/types.h> 00027 00028 /*** 00029 *** Intervals 00030 ***/ 00031 00032 /*! 00033 * \brief 00034 * The contents of this structure are private, and MUST NOT be accessed 00035 * directly by callers. 00036 * 00037 * The contents are exposed only to allow callers to avoid dynamic allocation. 00038 */ 00039 struct isc_interval { 00040 unsigned int seconds; 00041 unsigned int nanoseconds; 00042 }; 00043 00044 extern const isc_interval_t * const isc_interval_zero; 00045 00046 /* 00047 * ISC_FORMATHTTPTIMESTAMP_SIZE needs to be 30 in C locale and potentially 00048 * more for other locales to handle longer national abbreviations when 00049 * expanding strftime's %a and %b. 00050 */ 00051 #define ISC_FORMATHTTPTIMESTAMP_SIZE 50 00052 00053 ISC_LANG_BEGINDECLS 00054 00055 void 00056 isc_interval_set(isc_interval_t *i, 00057 unsigned int seconds, unsigned int nanoseconds); 00058 /*%< 00059 * Set 'i' to a value representing an interval of 'seconds' seconds and 00060 * 'nanoseconds' nanoseconds, suitable for use in isc_time_add() and 00061 * isc_time_subtract(). 00062 * 00063 * Requires: 00064 * 00065 *\li 't' is a valid pointer. 00066 *\li nanoseconds < 1000000000. 00067 */ 00068 00069 isc_boolean_t 00070 isc_interval_iszero(const isc_interval_t *i); 00071 /*%< 00072 * Returns ISC_TRUE iff. 'i' is the zero interval. 00073 * 00074 * Requires: 00075 * 00076 *\li 'i' is a valid pointer. 00077 */ 00078 00079 /*** 00080 *** Absolute Times 00081 ***/ 00082 00083 /*% 00084 * The contents of this structure are private, and MUST NOT be accessed 00085 * directly by callers. 00086 * 00087 * The contents are exposed only to allow callers to avoid dynamic allocation. 00088 */ 00089 00090 struct isc_time { 00091 unsigned int seconds; 00092 unsigned int nanoseconds; 00093 }; 00094 00095 extern const isc_time_t * const isc_time_epoch; 00096 00097 void 00098 isc_time_set(isc_time_t *t, unsigned int seconds, unsigned int nanoseconds); 00099 /*%< 00100 * Set 't' to a value which represents the given number of seconds and 00101 * nanoseconds since 00:00:00 January 1, 1970, UTC. 00102 * 00103 * Notes: 00104 *\li The Unix version of this call is equivalent to: 00105 *\code 00106 * isc_time_settoepoch(t); 00107 * isc_interval_set(i, seconds, nanoseconds); 00108 * isc_time_add(t, i, t); 00109 *\endcode 00110 * 00111 * Requires: 00112 *\li 't' is a valid pointer. 00113 *\li nanoseconds < 1000000000. 00114 */ 00115 00116 void 00117 isc_time_settoepoch(isc_time_t *t); 00118 /*%< 00119 * Set 't' to the time of the epoch. 00120 * 00121 * Notes: 00122 *\li The date of the epoch is platform-dependent. 00123 * 00124 * Requires: 00125 * 00126 *\li 't' is a valid pointer. 00127 */ 00128 00129 isc_boolean_t 00130 isc_time_isepoch(const isc_time_t *t); 00131 /*%< 00132 * Returns ISC_TRUE iff. 't' is the epoch ("time zero"). 00133 * 00134 * Requires: 00135 * 00136 *\li 't' is a valid pointer. 00137 */ 00138 00139 isc_result_t 00140 isc_time_now(isc_time_t *t); 00141 /*%< 00142 * Set 't' to the current absolute time. 00143 * 00144 * Requires: 00145 * 00146 *\li 't' is a valid pointer. 00147 * 00148 * Returns: 00149 * 00150 *\li Success 00151 *\li Unexpected error 00152 * Getting the time from the system failed. 00153 *\li Out of range 00154 * The time from the system is too large to be represented 00155 * in the current definition of isc_time_t. 00156 */ 00157 00158 isc_result_t 00159 isc_time_nowplusinterval(isc_time_t *t, const isc_interval_t *i); 00160 /*%< 00161 * Set *t to the current absolute time + i. 00162 * 00163 * Note: 00164 *\li This call is equivalent to: 00165 * 00166 *\code 00167 * isc_time_now(t); 00168 * isc_time_add(t, i, t); 00169 *\endcode 00170 * 00171 * Requires: 00172 * 00173 *\li 't' and 'i' are valid pointers. 00174 * 00175 * Returns: 00176 * 00177 *\li Success 00178 *\li Unexpected error 00179 * Getting the time from the system failed. 00180 *\li Out of range 00181 * The interval added to the time from the system is too large to 00182 * be represented in the current definition of isc_time_t. 00183 */ 00184 00185 int 00186 isc_time_compare(const isc_time_t *t1, const isc_time_t *t2); 00187 /*%< 00188 * Compare the times referenced by 't1' and 't2' 00189 * 00190 * Requires: 00191 * 00192 *\li 't1' and 't2' are valid pointers. 00193 * 00194 * Returns: 00195 * 00196 *\li -1 t1 < t2 (comparing times, not pointers) 00197 *\li 0 t1 = t2 00198 *\li 1 t1 > t2 00199 */ 00200 00201 isc_result_t 00202 isc_time_add(const isc_time_t *t, const isc_interval_t *i, isc_time_t *result); 00203 /*%< 00204 * Add 'i' to 't', storing the result in 'result'. 00205 * 00206 * Requires: 00207 * 00208 *\li 't', 'i', and 'result' are valid pointers. 00209 * 00210 * Returns: 00211 *\li Success 00212 *\li Out of range 00213 * The interval added to the time is too large to 00214 * be represented in the current definition of isc_time_t. 00215 */ 00216 00217 isc_result_t 00218 isc_time_subtract(const isc_time_t *t, const isc_interval_t *i, 00219 isc_time_t *result); 00220 /*%< 00221 * Subtract 'i' from 't', storing the result in 'result'. 00222 * 00223 * Requires: 00224 * 00225 *\li 't', 'i', and 'result' are valid pointers. 00226 * 00227 * Returns: 00228 *\li Success 00229 *\li Out of range 00230 * The interval is larger than the time since the epoch. 00231 */ 00232 00233 isc_uint64_t 00234 isc_time_microdiff(const isc_time_t *t1, const isc_time_t *t2); 00235 /*%< 00236 * Find the difference in microseconds between time t1 and time t2. 00237 * t2 is the subtrahend of t1; ie, difference = t1 - t2. 00238 * 00239 * Requires: 00240 * 00241 *\li 't1' and 't2' are valid pointers. 00242 * 00243 * Returns: 00244 *\li The difference of t1 - t2, or 0 if t1 <= t2. 00245 */ 00246 00247 isc_uint32_t 00248 isc_time_seconds(const isc_time_t *t); 00249 /*%< 00250 * Return the number of seconds since the epoch stored in a time structure. 00251 * 00252 * Requires: 00253 * 00254 *\li 't' is a valid pointer. 00255 */ 00256 00257 isc_result_t 00258 isc_time_secondsastimet(const isc_time_t *t, time_t *secondsp); 00259 /*%< 00260 * Ensure the number of seconds in an isc_time_t is representable by a time_t. 00261 * 00262 * Notes: 00263 *\li The number of seconds stored in an isc_time_t might be larger 00264 * than the number of seconds a time_t is able to handle. Since 00265 * time_t is mostly opaque according to the ANSI/ISO standard 00266 * (essentially, all you can be sure of is that it is an arithmetic type, 00267 * not even necessarily integral), it can be tricky to ensure that 00268 * the isc_time_t is in the range a time_t can handle. Use this 00269 * function in place of isc_time_seconds() any time you need to set a 00270 * time_t from an isc_time_t. 00271 * 00272 * Requires: 00273 *\li 't' is a valid pointer. 00274 * 00275 * Returns: 00276 *\li Success 00277 *\li Out of range 00278 */ 00279 00280 isc_uint32_t 00281 isc_time_nanoseconds(const isc_time_t *t); 00282 /*%< 00283 * Return the number of nanoseconds stored in a time structure. 00284 * 00285 * Notes: 00286 *\li This is the number of nanoseconds in excess of the number 00287 * of seconds since the epoch; it will always be less than one 00288 * full second. 00289 * 00290 * Requires: 00291 *\li 't' is a valid pointer. 00292 * 00293 * Ensures: 00294 *\li The returned value is less than 1*10^9. 00295 */ 00296 00297 void 00298 isc_time_formattimestamp(const isc_time_t *t, char *buf, unsigned int len); 00299 /*%< 00300 * Format the time 't' into the buffer 'buf' of length 'len', 00301 * using a format like "30-Aug-2000 04:06:47.997" and the local time zone. 00302 * If the text does not fit in the buffer, the result is indeterminate, 00303 * but is always guaranteed to be null terminated. 00304 * 00305 * Requires: 00306 *\li 'len' > 0 00307 *\li 'buf' points to an array of at least len chars 00308 * 00309 */ 00310 00311 void 00312 isc_time_formathttptimestamp(const isc_time_t *t, char *buf, unsigned int len); 00313 /*%< 00314 * Format the time 't' into the buffer 'buf' of length 'len', 00315 * using a format like "Mon, 30 Aug 2000 04:06:47 GMT" 00316 * If the text does not fit in the buffer, the result is indeterminate, 00317 * but is always guaranteed to be null terminated. 00318 * 00319 * Requires: 00320 *\li 'len' > 0 00321 *\li 'buf' points to an array of at least len chars 00322 * 00323 */ 00324 00325 isc_result_t 00326 isc_time_parsehttptimestamp(char *input, isc_time_t *t); 00327 /*%< 00328 * Parse the time in 'input' into the isc_time_t pointed to by 't', 00329 * expecting a format like "Mon, 30 Aug 2000 04:06:47 GMT" 00330 * 00331 * Requires: 00332 *\li 'buf' and 't' are not NULL. 00333 */ 00334 00335 void 00336 isc_time_formatISO8601(const isc_time_t *t, char *buf, unsigned int len); 00337 /*%< 00338 * Format the time 't' into the buffer 'buf' of length 'len', 00339 * using the ISO8601 format: "yyyy-mm-ddThh:mm:ssZ" 00340 * If the text does not fit in the buffer, the result is indeterminate, 00341 * but is always guaranteed to be null terminated. 00342 * 00343 * Requires: 00344 *\li 'len' > 0 00345 *\li 'buf' points to an array of at least len chars 00346 * 00347 */ 00348 00349 ISC_LANG_ENDDECLS 00350 00351 #endif /* ISC_TIME_H */