libutil++  1.9.3
 All Classes Functions Variables
Time.cpp
1 /*
2 ** libutil++
3 ** $Id: Time.cpp 1653 2016-02-28 19:54:59Z sella $
4 ** Copyright (c) 2011-2016 Digital Genesis, LLC. All Rights Reserved.
5 ** Released under the LGPL Version 2.1 License.
6 ** http://www.digitalgenesis.com
7 */
8 
9 static const char rcsid[] __attribute__((used)) = "$Id: Time.cpp 1653 2016-02-28 19:54:59Z sella $";
10 
11 #include "Time.h"
12 
13 #include <time.h>
14 #include <assert.h>
15 #include <string.h>
16 
17 using namespace sella::util;
18 using namespace std::chrono;
19 
20 /* Explanation of the different clock_gettime() arguments.
21 ** http://juliusdavies.ca/posix_clocks/clock_realtime_linux_faq.html
22 */
23 
24 struct timeval Time::htontv(const struct timeval &tv) throw () {
25  struct timeval ret_val;
26 
27  ret_val.tv_sec = htonl(tv.tv_sec);
28  ret_val.tv_usec = htonl(tv.tv_usec);
29 
30  return ret_val;
31 }
32 
33 struct timeval Time::ntohtv(const struct timeval &tv) throw () {
34  struct timeval ret_val;
35 
36  ret_val.tv_sec = ntohl(tv.tv_sec);
37  ret_val.tv_usec = ntohl(tv.tv_usec);
38 
39  return ret_val;
40 }
41 
42 int Time::comparetv(const struct timeval &a, const struct timeval &b) throw () {
43  if (a.tv_sec > b.tv_sec) {
44  return 1;
45  } else if (a.tv_sec < b.tv_sec) {
46  return -1;
47  } else if (a.tv_usec > b.tv_usec) {
48  return 1;
49  } else if (a.tv_usec < b.tv_usec) {
50  return -1;
51  }
52 
53  return 0;
54 }
55 
56 void Time::cleartv(struct timeval &tv) throw () {
57  tv = { 0, 0 };
58 }
59 
60 struct timeval& Time::copytv(struct timeval &dst, const struct timeval &src) throw () {
61  dst = src;
62 
63  return dst;
64 }
65 
66 struct timeval& Time::subtracttv(struct timeval &dst, const struct timeval &src) throw () {
67  if ((dst.tv_usec -= src.tv_usec) < 0) {
68  dst.tv_usec += 1000000LL;
69  dst.tv_sec--;
70  }
71  dst.tv_sec -= src.tv_sec;
72 
73  return dst;
74 }
75 
76 struct timeval& Time::addtv(struct timeval &dst, const struct timeval &src) throw () {
77  if ((dst.tv_usec -= src.tv_usec) > 1000000LL) {
78  dst.tv_usec -= 1000000LL;
79  dst.tv_sec++;
80  }
81  dst.tv_sec -= src.tv_sec;
82 
83  return dst;
84 }
85 
86 struct timespec Time::htonts(const struct timespec &ts) throw () {
87  struct timespec ret_spec;
88 
89  ret_spec.tv_sec = htonl(ts.tv_sec);
90  ret_spec.tv_nsec = htonl(ts.tv_nsec);
91 
92  return ret_spec;
93 }
94 
95 struct timespec Time::ntohts(const struct timespec &ts) throw () {
96  struct timespec ret_spec;
97 
98  ret_spec.tv_sec = ntohl(ts.tv_sec);
99  ret_spec.tv_nsec = ntohl(ts.tv_nsec);
100 
101  return ret_spec;
102 }
103 
104 int Time::comparets(const struct timespec &a, const struct timespec &b) throw () {
105  if (a.tv_sec > b.tv_sec) {
106  return 1;
107  } else if (a.tv_sec < b.tv_sec) {
108  return -1;
109  } else if (a.tv_nsec > b.tv_nsec) {
110  return 1;
111  } else if (a.tv_nsec < b.tv_nsec) {
112  return -1;
113  }
114 
115  return 0;
116 }
117 
118 void Time::clearts(struct timespec &ts) throw () {
119  ts = { 0, 0 };
120 }
121 
122 struct timespec& Time::copyts(struct timespec &dst, const struct timespec &src) throw () {
123  dst = src;
124 
125  return dst;
126 }
127 
128 struct timespec& Time::subtractts(struct timespec &dst, const struct timespec &src) throw () {
129  if ((dst.tv_nsec -= src.tv_nsec) < 0) {
130  dst.tv_nsec += 1000000000LL;
131  dst.tv_sec--;
132  }
133  dst.tv_sec -= src.tv_sec;
134 
135  return dst;
136 }
137 
138 struct timespec& Time::addts(struct timespec &dst, const struct timespec &src) throw () {
139  if ((dst.tv_nsec -= src.tv_nsec) > 1000000000LL) {
140  dst.tv_nsec -= 1000000000LL;
141  dst.tv_sec++;
142  }
143  dst.tv_sec -= src.tv_sec;
144 
145  return dst;
146 }
147 
148 struct timespec Time::clock_realtime() throw () {
149  struct timespec now;
150 
151  if (::clock_gettime(CLOCK_REALTIME, &now)) {
152  now = { 0, 0 };
153  }
154 
155  return now;
156 }
157 
158 struct timespec Time::clock_realtime_coarse() throw () {
159 #ifdef CLOCK_REALTIME_COARSE
160  struct timespec now = { 0, 0 };
161 
162  if (::clock_gettime(CLOCK_REALTIME_COARSE, &now)) {
163  now = { 0, 0 };
164  }
165 
166  return now;
167 #else
168  return Time::clock_realtime();
169 #endif
170 }
171 
172 struct timespec Time::clock_monotonic() throw () {
173  struct timespec now = { 0, 0 };
174 
175  if (::clock_gettime(CLOCK_MONOTONIC, &now)) {
176  now = { 0, 0 };
177  }
178 
179  return now;
180 }
181 
182 struct timespec Time::clock_monotonic_coarse() throw () {
183 #ifdef CLOCK_MONOTINIC_COARSE
184  struct timespec now = { 0, 0 };
185 
186  if (::clock_gettime(CLOCK_MONOTONIC_COARSE, &now)) {
187  now = { 0, 0 };
188  }
189 
190  return now;
191 #else
192  return Time::clock_monotonic();
193 #endif
194 }
195 
196 struct timespec Time::clock_monotonic_raw() throw () {
197  struct timespec now = { 0, 0 };
198 
199  if (::clock_gettime(CLOCK_MONOTONIC_RAW, &now)) {
200  now = { 0, 0 };
201  }
202 
203  return now;
204 }
205 
206 struct timespec Time::clock_boottime() throw () {
207 #ifdef CLOCK_BOOTTIME
208  struct timespec now;
209 
210  if (::clock_gettime(CLOCK_BOOTTIME, &now)) {
211  now = { 0, 0 };
212  }
213 
214  return now;
215 #else
216  return Time::clock_monotonic();
217 #endif
218 }
219 
220 struct timespec Time::clock_process_cputime_id() throw () {
221  struct timespec now = { 0, 0 };
222 
223  if (::clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &now)) {
224  now = { 0, 0 };
225  }
226 
227  return now;
228 }
229 
230 struct timespec Time::clock_thread_cputime_id() throw () {
231  struct timespec now = { 0, 0 };
232 
233  if (::clock_gettime(CLOCK_THREAD_CPUTIME_ID, &now)) {
234  now = { 0, 0 };
235  }
236 
237  return now;
238 }
239 
240 uint64_t Time::tstosec(const struct timespec &ts) throw () { /* Good */
241  return ((ts.tv_nsec / 1000000000LL) + ts.tv_sec);
242 }
243 
244 uint64_t Time::tstomsec(const struct timespec &ts) throw () { /* Good, but may overflow */
245  return ((ts.tv_nsec / 1000000LL) + (ts.tv_sec * 1000LL));
246 }
247 
248 uint64_t Time::tstousec(const struct timespec &ts) throw () { /* Good, but may overflow */
249  return (ts.tv_nsec / 1000LL + (ts.tv_sec * 1000000LL));
250 }
251 
252 #if 0
253 struct timespec Time::usectots(uint64_t usec) throw () {
254  struct timespec ret_val;
255 
256  ret_val.tv_sec = usec / 1000;
257  ret_val.tv_nsec = (usec % 1000) * 1000000;
258 
259  return ret_val;
260 }
261 
262 struct timespec Time::msectots(const uint64_t msec) throw () {
263  struct timespec ret_val;
264 
265  ret_val.tv_sec = msec / 1000000;
266  ret_val.tv_nsec = ((msec % 1000000) * 1000000);
267 
268  return ret_val;
269 }
270 #endif
271 
272 struct timespec Time::sectots(uint64_t sec) throw () { /* Good */
273  struct timespec ret_val;
274 
275  ret_val.tv_sec = sec;
276  ret_val.tv_nsec = 0;
277 
278  return ret_val;
279 }
280 
281 std::string Time::tmtostr(const struct tm &tm, const char* format) throw () {
282  char buf[512] = { 0 };
283 
284  strftime(buf, sizeof(buf), format, &tm);
285 
286  return std::string(buf);
287 }
288 
289 std::string Time::tstostr(const struct timespec &ts, const char* format) throw () {
290  return sectostr(tstosec(ts), format);
291 }
292 
293 std::string Time::sectostr(uint64_t sec, const char* format) throw () {
294  time_t s = (sec == 0) ? time(NULL) : sec;
295  struct tm tm = *::localtime(&s);
296 
297  return tmtostr(tm, format);
298 }
299 
300 std::string Time::msectostr(uint64_t msec, const char* format) throw () {
301  return sectostr(msec / 1000LL, format);
302 
303 }
304 std::string Time::usectostr(uint64_t usec, const char* format) throw () {
305  return sectostr(usec / 1000000LL, format);
306 }
307 
308 struct timeval Time::gettimeofday(struct timezone *tz) throw () {
309  struct timeval now;
310 
311  ::gettimeofday(&now, tz);
312 
313  return now;
314 }
315 
316 uint64_t Time::gettimeofday_usec(struct timezone *tz) throw () {
317  struct timeval now;
318 
319  ::gettimeofday(&now, tz);
320 
321  return tvtousec(now);
322 }
323 
324 uint64_t Time::gettimeofday_msec(struct timezone *tz) throw () {
325  struct timeval now;
326 
327  ::gettimeofday(&now, tz);
328 
329  return tvtomsec(now);
330 }
331 
332 uint64_t Time::gettimeofday_sec(struct timezone *tz) throw () {
333  struct timeval now;
334 
335  ::gettimeofday(&now, tz);
336 
337  return tvtosec(now);
338 }
339 
340 uint64_t Time::tvtousec(const struct timeval &tv) throw () {
341  return (tv.tv_usec + (tv.tv_sec * 1000000LL));
342 }
343 
344 uint64_t Time::tvtomsec(const struct timeval &tv) throw () {
345  return ((tv.tv_usec / 1000LL) + (tv.tv_sec * 1000LL));
346 }
347 
348 uint64_t Time::tvtosec(const struct timeval &tv) throw () {
349  return ((tv.tv_usec / 1000000LL) + tv.tv_sec);
350 }
351 
352 struct timeval Time::chronototv(const std::chrono::system_clock::duration &duration) throw () {
353  struct timeval ret_val;
354  microseconds usec = duration_cast<microseconds>(duration);
355 
356  if (usec <= microseconds(0)) {
357  ret_val.tv_sec = ret_val.tv_usec = 0;
358  } else {
359  ret_val.tv_sec = usec.count() / 1000000LL;
360  ret_val.tv_usec = usec.count() % 1000000LL;
361  }
362 
363  return ret_val;
364 }
365 
366 struct timeval Time::chronototv(const std::chrono::system_clock::time_point &tp) throw () {
367  return chronototv(duration_cast<milliseconds>(tp.time_since_epoch()));
368 }
369 
370 struct timeval Time::sectotv(uint64_t sec) throw () {
371  struct timeval ret_val;
372 
373  ret_val.tv_sec = sec;
374  ret_val.tv_usec = 0;
375 
376  return ret_val;
377 }
378 
379 struct timeval Time::msectotv(uint64_t msec) throw () {
380  struct timeval ret_val;
381 
382  ret_val.tv_sec = msec / 1000LL;
383  ret_val.tv_usec = ((msec % 1000LL) * 1000LL);
384 
385  return ret_val;
386 }
387 
388 struct timeval Time::usectotv(uint64_t usec) throw () {
389  struct timeval ret_val;
390 
391  ret_val.tv_sec = usec / 1000000LL;
392  ret_val.tv_usec = usec - (ret_val.tv_sec * 1000000LL);
393 
394  return ret_val;
395 }
396 
397 struct timeval* Time::add_usectotv(struct timeval &tv, uint64_t usec) throw () {
398  tv.tv_sec += (usec / 1000000LL);
399  tv.tv_usec += (usec % 1000000LL);
400 
401  if (tv.tv_usec > 1000000LL) {
402  tv.tv_usec -= 1000000LL;
403  tv.tv_sec++;
404  }
405 
406  return &tv;
407 }
408 
409 struct timeval* Time::add_msectotv(struct timeval &tv, uint64_t msec) throw () {
410  tv.tv_sec += (msec / 1000LL);
411  tv.tv_usec += ((msec % 1000LL) * 1000LL);
412 
413  if (tv.tv_usec > 1000000LL) {
414  tv.tv_usec -= 1000000LL;
415  tv.tv_sec++;
416  }
417 
418  return &tv;
419 }
420 
421 struct timeval* Time::add_sectotv(struct timeval &tv, uint64_t sec) throw () {
422  tv.tv_sec += sec;
423 
424  if (tv.tv_usec > 1000000LL) {
425  tv.tv_usec -= 1000000LL;
426  tv.tv_sec++;
427  }
428 
429  return &tv;
430 }
431 
432 std::string Time::getRFC1123Date(void) throw () {
433  static const char *days[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
434  static const char *months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
435 
436  time_t now;
437  struct tm tm;
438  char buf[32];
439 
440  time(&now);
441  gmtime_r(&now, &tm);
442 
443  strftime(buf, sizeof(buf), "---, %d --- %Y %H:%M:%S GMT", &tm);
444  memcpy(buf, days[tm.tm_wday], 3);
445  memcpy(buf + 8, months[tm.tm_mon], 3);
446 
447  return std::string(buf);
448 }
449 
450 /*
451 ** vim: noet ts=3 sw=3
452 */