Asterisk - The Open Source Telephony Project  21.4.1
time.h
Go to the documentation of this file.
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2005, Digium, Inc.
5  *
6  * Mark Spencer <markster@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18 
19 /*! \file
20  * \brief Time-related functions and macros
21  */
22 
23 #ifndef _ASTERISK_TIME_H
24 #define _ASTERISK_TIME_H
25 
26 #include "asterisk/autoconfig.h"
27 
28 #ifdef HAVE_SYS_TIME_H
29 #include <sys/time.h>
30 #endif
31 
32 #ifdef HAVE_UNISTD_H
33 #include <unistd.h>
34 #endif
35 
36 #include <math.h>
37 
38 #include "asterisk/inline_api.h"
39 
40 /* A time_t can be represented as an unsigned long long (or uint64_t).
41  * Formatted in base 10, UINT64_MAX is 20 digits long, plus one for NUL.
42  * This should be the size of the receiving char buffer for calls to
43  * ast_time_t_to_string().
44  */
45 #define AST_TIME_T_LEN 21
46 
47 /* We have to let the compiler learn what types to use for the elements of a
48  struct timeval since on linux, it's time_t and suseconds_t, but on *BSD,
49  they are just a long.
50  note:dummy_tv_var_for_types never actually gets exported, only used as
51  local place holder. */
52 extern struct timeval dummy_tv_var_for_types;
53 typedef typeof(dummy_tv_var_for_types.tv_sec) ast_time_t;
54 typedef typeof(dummy_tv_var_for_types.tv_usec) ast_suseconds_t;
55 
56 /*!
57  * \brief Computes the difference (in seconds) between two \c struct \c timeval instances.
58  * \param end the end of the time period
59  * \param start the beginning of the time period
60  * \return the difference in seconds
61  */
62 AST_INLINE_API(
63 int64_t ast_tvdiff_sec(struct timeval end, struct timeval start),
64 {
65  int64_t result = end.tv_sec - start.tv_sec;
66  if (result > 0 && end.tv_usec < start.tv_usec)
67  result--;
68  else if (result < 0 && end.tv_usec > start.tv_usec)
69  result++;
70 
71  return result;
72 }
73 )
74 
75 /*!
76  * \brief Computes the difference (in microseconds) between two \c struct \c timeval instances.
77  * \param end the end of the time period
78  * \param start the beginning of the time period
79  * \return the difference in microseconds
80  */
81 AST_INLINE_API(
82 int64_t ast_tvdiff_us(struct timeval end, struct timeval start),
83 {
84  return (end.tv_sec - start.tv_sec) * (int64_t) 1000000 +
85  end.tv_usec - start.tv_usec;
86 }
87 )
88 
89 /*!
90  * \brief Computes the difference (in milliseconds) between two \c struct \c timeval instances.
91  * \param end end of the time period
92  * \param start beginning of the time period
93  * \return the difference in milliseconds
94  */
95 AST_INLINE_API(
96 int64_t ast_tvdiff_ms(struct timeval end, struct timeval start),
97 {
98  /* the offset by 1,000,000 below is intentional...
99  it avoids differences in the way that division
100  is handled for positive and negative numbers, by ensuring
101  that the divisor is always positive
102  */
103  int64_t sec_dif = (int64_t)(end.tv_sec - start.tv_sec) * 1000;
104  int64_t usec_dif = (1000000 + end.tv_usec - start.tv_usec) / 1000 - 1000;
105  return sec_dif + usec_dif;
106 }
107 )
108 
109 /*!
110  * \brief Returns true if the argument is 0,0
111  */
112 AST_INLINE_API(
113 int ast_tvzero(const struct timeval t),
114 {
115  return (t.tv_sec == 0 && t.tv_usec == 0);
116 }
117 )
118 
119 /*!
120  * \brief Compress two \c struct \c timeval instances returning
121  * -1, 0, 1 if the first arg is smaller, equal or greater to the second.
122  */
123 AST_INLINE_API(
124 int ast_tvcmp(struct timeval _a, struct timeval _b),
125 {
126  if (_a.tv_sec < _b.tv_sec)
127  return -1;
128  if (_a.tv_sec > _b.tv_sec)
129  return 1;
130  /* now seconds are equal */
131  if (_a.tv_usec < _b.tv_usec)
132  return -1;
133  if (_a.tv_usec > _b.tv_usec)
134  return 1;
135  return 0;
136 }
137 )
138 
139 /*!
140  * \brief Returns true if the two \c struct \c timeval arguments are equal.
141  */
142 AST_INLINE_API(
143 int ast_tveq(struct timeval _a, struct timeval _b),
144 {
145  return (_a.tv_sec == _b.tv_sec && _a.tv_usec == _b.tv_usec);
146 }
147 )
148 
149 /*!
150  * \brief Returns current timeval. Meant to replace calls to gettimeofday().
151  */
152 AST_INLINE_API(
153 struct timeval ast_tvnow(void),
154 {
155  struct timeval t;
156  gettimeofday(&t, NULL);
157  return t;
158 }
159 )
160 
161 /*!
162  * \brief Returns current timespec. Meant to avoid calling ast_tvnow() just to
163  * create a timespec from the timeval it returns.
164  */
165 #if defined _POSIX_TIMERS && _POSIX_TIMERS > 0
166 AST_INLINE_API(
167 struct timespec ast_tsnow(void),
168 {
169  struct timespec ts;
170  clock_gettime(CLOCK_REALTIME, &ts);
171  return ts;
172 }
173 )
174 #else
175 AST_INLINE_API(
176 struct timespec ast_tsnow(void),
177 {
178  struct timeval tv = ast_tvnow();
179  struct timespec ts;
180  /* Can't use designated initializer, because it does odd things with
181  * the AST_INLINE_API macro. Go figure. */
182  ts.tv_sec = tv.tv_sec;
183  ts.tv_nsec = tv.tv_usec * 1000;
184  return ts;
185 }
186 )
187 #endif
188 
189 /*!
190  * \brief Returns the sum of two timevals a + b
191  */
192 struct timeval ast_tvadd(struct timeval a, struct timeval b);
193 
194 /*!
195  * \brief Returns the difference of two timevals a - b
196  */
197 struct timeval ast_tvsub(struct timeval a, struct timeval b);
198 
199 /*!
200  * \since 12
201  * \brief Formats a duration into HH:MM:SS
202  *
203  * \param duration The time (in seconds) to format
204  * \param buf A buffer to hold the formatted string'
205  * \param length The size of the buffer
206  */
207 void ast_format_duration_hh_mm_ss(int duration, char *buf, size_t length);
208 
209 
210 /*!
211  * \brief Calculate remaining milliseconds given a starting timestamp
212  * and upper bound
213  *
214  * If the upper bound is negative, then this indicates that there is no
215  * upper bound on the amount of time to wait. This will result in a
216  * negative return.
217  *
218  * \param start When timing started being calculated
219  * \param max_ms The maximum number of milliseconds to wait from start. May be negative.
220  * \return The number of milliseconds left to wait for. May be negative.
221  */
222 int ast_remaining_ms(struct timeval start, int max_ms);
223 
224 /*!
225  * \brief Returns a timeval from sec, usec
226  */
227 AST_INLINE_API(
228 struct timeval ast_tv(ast_time_t sec, ast_suseconds_t usec),
229 {
230  struct timeval t;
231  t.tv_sec = sec;
232  t.tv_usec = usec;
233  return t;
234 }
235 )
236 
237 /*!
238  * \brief Returns a timeval structure corresponding to the
239  * number of seconds in the double _td.
240  *
241  * \param _td The number of seconds.
242  * \returns A timeval structure containing the number of seconds.
243  *
244  * This is the inverse of ast_tv2double().
245  */
246 AST_INLINE_API(
247 struct timeval ast_double2tv(double _td),
248 {
249  struct timeval t;
250  t.tv_sec = (typeof(t.tv_sec))floor(_td);
251  t.tv_usec = (typeof(t.tv_usec)) ((_td - t.tv_sec) * 1000000.0);
252  return t;
253 }
254 )
255 
256 /*!
257  * \brief Returns a double corresponding to the number of seconds
258  * in the timeval \c tv.
259  *
260  * \param tv A pointer to a timeval structure.
261  * \returns A double containing the number of seconds.
262  *
263  * This is the inverse of ast_double2tv().
264  */
265 AST_INLINE_API(
266 double ast_tv2double(const struct timeval *tv),
267 {
268  return (((double)tv->tv_sec) + (((double)tv->tv_usec) / 1000000.0));
269 }
270 )
271 
272 /*!
273  * \brief Returns a timeval corresponding to the duration of n samples at rate r.
274  * Useful to convert samples to timevals, or even milliseconds to timevals
275  * in the form ast_samp2tv(milliseconds, 1000)
276  */
277 AST_INLINE_API(
278 struct timeval ast_samp2tv(unsigned int _nsamp, unsigned int _rate),
279 {
280  return ast_tv(_nsamp / _rate, (_nsamp % _rate) * (1000000 / (float) _rate));
281 }
282 )
283 
284 /*!
285  * \brief Returns the number of samples at rate _rate in the
286  * duration specified by _tv.
287  *
288  * \param _tv A pointer to a timeval structure.
289  * \param _rate The sample rate in Hz.
290  * \returns A time_t containing the number of samples.
291  *
292  * This is the inverse of ast_samp2tv().
293  */
294 AST_INLINE_API(
295 time_t ast_tv2samp(const struct timeval *_tv, int _rate),
296 {
297  return (time_t)(ast_tv2double(_tv) * (double)_rate);
298 }
299 )
300 
301 /*!
302  * \brief Returns the duration in seconds of _nsamp samples
303  * at rate _rate.
304  *
305  * \param _nsamp The number of samples
306  * \param _rate The sample rate in Hz.
307  * \returns A double containing the number of seconds.
308  *
309  * This is the inverse of ast_sec2samp().
310  */
311 AST_INLINE_API(
312 double ast_samp2sec(unsigned int _nsamp, unsigned int _rate),
313 {
314  return ((double)_nsamp) / ((double)_rate);
315 }
316 )
317 
318 /*!
319  * \brief Returns the number of samples at _rate in the duration
320  * in _seconds.
321  *
322  * \param _seconds The time interval in seconds.
323  * \param _rate The sample rate in Hz.
324  * \returns The number of samples.
325  *
326  * This is the inverse of ast_samp2sec().
327  */
328 AST_INLINE_API(
329 unsigned int ast_sec2samp(double _seconds, int _rate),
330 {
331  return (unsigned int)(_seconds * _rate);
332 }
333 )
334 
335 /*!
336  * \brief Time units enumeration.
337  */
338 enum TIME_UNIT {
339  TIME_UNIT_ERROR = -1,
340  TIME_UNIT_NANOSECOND,
341  TIME_UNIT_MICROSECOND,
342  TIME_UNIT_MILLISECOND,
343  TIME_UNIT_SECOND,
344  TIME_UNIT_MINUTE,
345  TIME_UNIT_HOUR,
346  TIME_UNIT_DAY,
347  TIME_UNIT_WEEK,
348  TIME_UNIT_MONTH,
349  TIME_UNIT_YEAR,
350 };
351 
352 /*!
353  * \brief Convert a string to a time unit enumeration value.
354  *
355  * This method attempts to be as flexible, and forgiving as possible when
356  * converting. In most cases the algorithm will match on the beginning of
357  * up to three strings (short, medium, long form). So that means if the
358  * given string at least starts with one of the form values it will match.
359  *
360  * For example: us, usec, microsecond will all map to TIME_UNIT_MICROSECOND.
361  * So will uss, usecs, microseconds, or even microsecondvals
362  *
363  * Matching is also not case sensitive.
364  *
365  * \param unit The string to map to an enumeration
366  *
367  * \return A time unit enumeration
368  */
369 enum TIME_UNIT ast_time_str_to_unit(const char *unit);
370 
371 /*!
372  * \brief Convert a timeval structure to microseconds
373  *
374  * \param tv The timeval to convert
375  *
376  * \return The time in microseconds
377  */
378 ast_suseconds_t ast_time_tv_to_usec(const struct timeval *tv);
379 
380 /*!
381  * \brief Create a timeval object initialized to given values.
382  *
383  * \param sec The timeval seconds value
384  * \param usec The timeval microseconds value
385  *
386  * \return A timeval object
387  */
388 struct timeval ast_time_create(ast_time_t sec, ast_suseconds_t usec);
389 
390 /*!
391  * \brief Convert the given unit value, and create a timeval object from it.
392  *
393  * \param val The value to convert to a timeval
394  * \param unit The time unit type of val
395  *
396  * \return A timeval object
397  */
398 struct timeval ast_time_create_by_unit(unsigned long val, enum TIME_UNIT unit);
399 
400 /*!
401  * \brief Convert the given unit value, and create a timeval object from it.
402  *
403  * This will first attempt to convert the unit from a string to a TIME_UNIT
404  * enumeration. If that conversion fails then a zeroed out timeval object
405  * is returned.
406  *
407  * \param val The value to convert to a timeval
408  * \param unit The time unit type of val
409  *
410  * \return A timeval object
411  */
412 struct timeval ast_time_create_by_unit_str(unsigned long val, const char *unit);
413 
414 /*!
415  * \brief Converts to a string representation of a time_t as decimal
416  * seconds since the epoch. Returns -1 on failure, zero otherwise.
417  *
418  * The buffer should be at least 22 bytes long.
419  */
420 int ast_time_t_to_string(time_t time, char *buf, size_t length);
421 
422 /*!
423  * \brief Returns a time_t from a string containing seconds since the epoch.
424  */
425 time_t ast_string_to_time_t(const char *str);
426 
427 #endif /* _ASTERISK_TIME_H */
time_t ast_string_to_time_t(const char *str)
Returns a time_t from a string containing seconds since the epoch.
Definition: time.c:163
ast_suseconds_t ast_time_tv_to_usec(const struct timeval *tv)
Convert a timeval structure to microseconds.
Definition: time.c:90
unsigned int ast_sec2samp(double _seconds, int _rate)
Returns the number of samples at _rate in the duration in _seconds.
Definition: time.h:333
int ast_time_t_to_string(time_t time, char *buf, size_t length)
Converts to a string representation of a time_t as decimal seconds since the epoch. Returns -1 on failure, zero otherwise.
Definition: time.c:152
int ast_tveq(struct timeval _a, struct timeval _b)
Returns true if the two struct timeval arguments are equal.
Definition: time.h:147
int64_t ast_tvdiff_sec(struct timeval end, struct timeval start)
Computes the difference (in seconds) between two struct timeval instances.
Definition: time.h:73
TIME_UNIT
Time units enumeration.
Definition: time.h:338
struct timeval ast_time_create_by_unit_str(unsigned long val, const char *unit)
Convert the given unit value, and create a timeval object from it.
Definition: time.c:143
int ast_tvzero(const struct timeval t)
Returns true if the argument is 0,0.
Definition: time.h:117
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:159
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:107
Inlinable API function macro.
struct timeval ast_samp2tv(unsigned int _nsamp, unsigned int _rate)
Returns a timeval corresponding to the duration of n samples at rate r. Useful to convert samples to ...
Definition: time.h:282
double ast_samp2sec(unsigned int _nsamp, unsigned int _rate)
Returns the duration in seconds of _nsamp samples at rate _rate.
Definition: time.h:316
int ast_tvcmp(struct timeval _a, struct timeval _b)
Compress two struct timeval instances returning -1, 0, 1 if the first arg is smaller, equal or greater to the second.
Definition: time.h:137
struct timeval ast_double2tv(double _td)
Returns a timeval structure corresponding to the number of seconds in the double _td.
Definition: time.h:254
int ast_remaining_ms(struct timeval start, int max_ms)
Calculate remaining milliseconds given a starting timestamp and upper bound.
Definition: utils.c:2281
time_t ast_tv2samp(const struct timeval *_tv, int _rate)
Returns the number of samples at rate _rate in the duration specified by _tv.
Definition: time.h:299
struct timeval ast_tvadd(struct timeval a, struct timeval b)
Returns the sum of two timevals a + b.
Definition: extconf.c:2282
struct timeval ast_time_create(ast_time_t sec, ast_suseconds_t usec)
Create a timeval object initialized to given values.
Definition: time.c:95
enum TIME_UNIT ast_time_str_to_unit(const char *unit)
Convert a string to a time unit enumeration value.
Definition: time.c:66
struct timeval ast_tv(ast_time_t sec, ast_suseconds_t usec)
Returns a timeval from sec, usec.
Definition: time.h:235
struct timespec ast_tsnow(void)
Returns current timespec. Meant to avoid calling ast_tvnow() just to create a timespec from the timev...
Definition: time.h:186
double ast_tv2double(const struct timeval *tv)
Returns a double corresponding to the number of seconds in the timeval tv.
Definition: time.h:270
struct timeval ast_tvsub(struct timeval a, struct timeval b)
Returns the difference of two timevals a - b.
Definition: extconf.c:2297
int64_t ast_tvdiff_us(struct timeval end, struct timeval start)
Computes the difference (in microseconds) between two struct timeval instances.
Definition: time.h:87
void ast_format_duration_hh_mm_ss(int duration, char *buf, size_t length)
Formats a duration into HH:MM:SS.
Definition: utils.c:2297
struct timeval ast_time_create_by_unit(unsigned long val, enum TIME_UNIT unit)
Convert the given unit value, and create a timeval object from it.
Definition: time.c:113