PicoScenes API Docs
 
Loading...
Searching...
No Matches
TimeTools.hxx
Go to the documentation of this file.
1//
2// Created by Zhiping Jiang on 3/4/21.
3//
4
5#ifndef PICOSCENES_PLATFORM_TIMETOOLS_HXX
6#define PICOSCENES_PLATFORM_TIMETOOLS_HXX
7
8#include <iomanip>
9#include <chrono>
10#include <thread>
11#include "BoostHeaders.hxx"
12
13#define DATEFORMAT "%Y-%m-%d %T"
14
15using namespace std::chrono_literals;
16
20typedef std::chrono::time_point<std::chrono::system_clock, std::chrono::milliseconds> TimePoint_System_Millisecond;
21
25typedef std::chrono::time_point<std::chrono::system_clock, std::chrono::milliseconds> TimePoint_System_Microsecond;
26
30typedef std::chrono::time_point<std::chrono::system_clock, std::chrono::milliseconds> TimePoint_System_Second;
31
38std::ostream &operator<<(std::ostream &os, const std::chrono::system_clock::time_point &t);
39
46std::ostream &operator<<(std::ostream &os, const timespec &ts);
47
48#if !(defined (_WIN32) || defined(WIN32))
55std::ostream &operator<<(std::ostream &os, const timeval &tv);
56#endif
57
59
66 template<typename TimeUnit = std::chrono::seconds>
67 std::chrono::duration<TimeUnit> time_t2Duration(const time_t time) {
68 return std::chrono::time_point_cast<TimeUnit>(std::chrono::seconds(time));
69 }
70
77 template<typename TimeUnit>
78 time_t duration2Time_t(const std::chrono::duration<TimeUnit> &duration) {
79 auto sec_dur = std::chrono::duration_cast<std::chrono::seconds>(duration);
80 return sec_dur.count();
81 }
82
89 template<typename TimeUnit = std::chrono::nanoseconds, typename Rep = typename TimeUnit::rep, typename Period = typename TimeUnit::period>
90 std::chrono::duration<Rep, Period> timespec2Duration(const timespec &ts) {
91 auto duration = std::chrono::seconds{ts.tv_sec} + std::chrono::nanoseconds{ts.tv_nsec};
92 return std::chrono::duration_cast<TimeUnit>(duration);
93 }
94
102 template<typename Rep, typename Period>
103 struct timespec duration2Timespec(const std::chrono::duration<Rep, Period> &dur) {
104 auto sec_dur = std::chrono::duration_cast<std::chrono::seconds>(dur);
105 auto remain_dur = dur - sec_dur;
106 auto remain_nano_dur = std::chrono::duration_cast<std::chrono::nanoseconds>(remain_dur);
107 return timespec{
108 .tv_sec = sec_dur.count(),
109 .tv_nsec = static_cast<long>(remain_nano_dur.count()),
110 };
111 }
112
113#if !(defined (_WIN32) || defined(WIN32))
120 template<typename TimeUnit = std::chrono::microseconds>
121 std::chrono::duration<TimeUnit> timeval2Duration(const timeval &tv) {
122 auto duration = std::chrono::seconds{tv.tv_sec} + std::chrono::microseconds{tv.tv_usec};
123 return std::chrono::duration_cast<TimeUnit>(duration);
124 }
125
132 template<typename TimeUnit>
133 struct timeval duration2Timeval(const std::chrono::duration<TimeUnit> &dur) {
134 auto sec_dur = std::chrono::duration_cast<std::chrono::seconds>(dur);
135 auto remain_dur = dur - sec_dur;
136 auto remain_micro_dur = std::chrono::duration_cast<std::chrono::microseconds>(remain_dur);
137 return timeval{
138 .tv_sec = sec_dur.count(),
139 .tv_usec = remain_micro_dur.count(),
140 };
141 }
142#endif
143
150 template<typename Duration = std::chrono::seconds>
151 std::chrono::time_point<std::chrono::system_clock, Duration> time_t2TimePoint(const time_t time) {
152 return std::chrono::time_point_cast<Duration>(std::chrono::time_point<std::chrono::system_clock, std::chrono::seconds>(std::chrono::seconds(time)));
153 }
154
161 template<typename Duration>
162 time_t time_point2Time_t(const std::chrono::time_point<std::chrono::system_clock, Duration> &tp) {
163 auto sec_tp = std::chrono::time_point_cast<std::chrono::seconds, std::chrono::system_clock, Duration>(tp);
164 return sec_tp.time_since_epoch().count();
165 }
166
173 template<typename Duration = std::chrono::nanoseconds>
174 std::chrono::time_point<std::chrono::system_clock, Duration> timespec2TimePoint(const timespec &ts) {
175 return std::chrono::time_point<std::chrono::system_clock, Duration>(std::chrono::duration_cast<Duration>(timespec2Duration<Duration>(ts)));
176 }
177
178#if !(defined (_WIN32) || defined(WIN32))
185 template<typename Duration = std::chrono::microseconds>
186 std::chrono::time_point<std::chrono::system_clock, Duration> timeval2TimePoint(const timeval &tv) {
187 return std::chrono::time_point<std::chrono::system_clock, Duration>(std::chrono::duration_cast<Duration>(timeval2Duration<Duration>(tv)));
188 }
189#endif
190
197 template<typename Duration>
198 timespec time_point2Timespec(const std::chrono::time_point<std::chrono::system_clock, Duration> &tp) {
199 auto sec_tp = std::chrono::time_point_cast<std::chrono::seconds>(tp);
200 auto nano_dur = std::chrono::duration_cast<std::chrono::nanoseconds>(tp - sec_tp);
201 return timespec{
202 .tv_sec = sec_tp.time_since_epoch().count(),
203 .tv_nsec = static_cast<long>(nano_dur.count()),
204 };
205 }
206
207#if !(defined (_WIN32) || defined(WIN32))
214 template<typename Duration>
215 timeval time_point2Timeval(const std::chrono::time_point<std::chrono::system_clock, Duration> &tp) {
216 auto sec_tp = std::chrono::time_point_cast<std::chrono::seconds>(tp);
217 auto micro_dur = std::chrono::duration_cast<std::chrono::microseconds>(tp - sec_tp);
218 return timeval{
219 .tv_sec = sec_tp.time_since_epoch().count(),
220 .tv_usec = micro_dur.count(),
221 };
222 }
223#endif
224
230 static timespec time_t2Timespec(const time_t time) {
231 return timespec{
232 .tv_sec = time,
233 .tv_nsec = 0,
234 };
235 }
236
242 static time_t timespec2Time_t(const timespec &ts) {
243 return ts.tv_sec;
244 }
245
246#if !(defined (_WIN32) || defined(WIN32))
252 static timeval time_t2timeval(time_t time) {
253 return timeval{
254 .tv_sec = time,
255 .tv_usec = 0,
256 };
257 }
258
264 static time_t timeval2Time_t(const timeval &tv) {
265 return tv.tv_sec;
266 }
267#endif
268
275 static std::string time_t2String(const time_t time, const std::string &format = DATEFORMAT) {
276 std::stringstream ss;
277 ss << std::put_time(std::localtime(&time), format.c_str());
278 return ss.str();
279 }
280
287 static std::string timespec2String(const timespec &ts, const std::string &format = DATEFORMAT) {
288 std::stringstream ss;
289 time_t time = timespec2Time_t(ts);
290 ss << std::put_time(std::localtime(&time), format.c_str());
291 return ss.str();
292 }
293
294#if !(defined (_WIN32) || defined(WIN32))
301 static std::string timeval2String(const timeval &tv, const std::string &format = DATEFORMAT) {
302 std::stringstream ss;
303 time_t time = timeval2Time_t(tv);
304 ss << std::put_time(std::localtime(&time), format.c_str());
305 return ss.str();
306 }
307#endif
308
316 template<typename Duration>
317 std::string time_point2String(const std::chrono::time_point<std::chrono::system_clock, Duration> &tp, const std::string &format = DATEFORMAT) {
318 auto sec_tp = std::chrono::time_point_cast<std::chrono::seconds>(tp);
319 auto timet = std::chrono::system_clock::to_time_t(sec_tp);
320 return time_t2String(timet, format);
321 }
322
330 template<typename TimeUnit>
331 std::string duration2String(const std::chrono::duration<TimeUnit> &duration, const std::string &format = DATEFORMAT) {
332 auto time_t = duration2Time_t(duration);
333 return time_t2String(time_t, format);
334 }
335
342 static time_t string2time_t(const std::string &timeString, const std::string &timeStringFormat = DATEFORMAT) {
343 // FIXME: time conv
344 #if !(defined (_WIN32) || defined (WIN32))
345 std::tm tm = {};
346 strptime(timeString.c_str(), timeStringFormat.c_str(), &tm);
347 auto time = timelocal(&tm);
348 return time;
349 #else
350 std::tm tm = {};
351
352 // HACK: no time zone support
353 if (timeStringFormat.find("%Z") != std::string::npos || timeStringFormat.find("%z") != std::string::npos) {
354 std::string tzformat, timestr;
355 if (timeStringFormat.compare(0, 3, "%z ") == 0) {
356 tzformat = timeStringFormat.substr(3);
357 timestr = timeString.substr(timeString.find(' ') + 1);
358 } else if (timeStringFormat.compare(timeStringFormat.size() - 3, 3, " %Z") == 0) {
359 tzformat = timeStringFormat.substr(0, timeStringFormat.size() - 3);
360 timestr = timeString.substr(0, timeString.find_last_of(' '));
361 } else {
362 throw std::runtime_error(timeStringFormat + " unsupported");
363 }
364
365 std::istringstream ss(timestr);
366
367 // Use std::get_time to parse the string based on the format
368 ss >> std::get_time(&tm, tzformat.c_str());
369
370 if (ss.fail()) {
371 throw std::runtime_error("Failed to parse time");
372 }
373
374 tm.tm_isdst = -1;
375
376 // Convert std::tm to time_t (mktime assumes local time)
377 return _mkgmtime(&tm);
378 } else {
379 std::istringstream ss(timeString);
380
381 // Use std::get_time to parse the string based on the format
382 ss >> std::get_time(&tm, timeStringFormat.c_str());
383
384 if (ss.fail()) {
385 throw std::runtime_error("Failed to parse time");
386 }
387
388 tm.tm_isdst = -1;
389
390 // Convert std::tm to time_t (mktime assumes local time)
391 return mktime(&tm);
392 }
393 #endif
394 }
395
402 static struct timespec string2Timespec(const std::string &timeString, const std::string &timeStringFormat = DATEFORMAT) {
403 return time_t2Timespec(string2time_t(timeString, timeStringFormat));
404 }
405
413 template<typename Duration = std::chrono::seconds>
414 std::chrono::time_point<std::chrono::system_clock, Duration> string2time_point(const std::string &timeString, const std::string &timeStringFormat = DATEFORMAT) {
415 auto time_t = string2time_t(timeString, timeStringFormat);
416 return time_t2TimePoint<Duration>(time_t);
417 }
418
426 template<typename TimeUnit = std::chrono::seconds>
427 static std::chrono::duration<TimeUnit> string2Duration(const std::string &timeString, const std::string &timeStringFormat = DATEFORMAT) {
428 auto time_t = string2time_t(timeString, timeStringFormat);
429 return time_t2Duration<TimeUnit>(time_t);
430 }
431
437 int32_t delay_periodic(int32_t delay_us);
438}
439
440#endif //PICOSCENES_PLATFORM_TIMETOOLS_HXX
std::chrono::time_point< std::chrono::system_clock, std::chrono::milliseconds > TimePoint_System_Millisecond
Type alias for system time points with millisecond precision.
Definition TimeTools.hxx:20
#define DATEFORMAT
Definition TimeTools.hxx:13
std::chrono::time_point< std::chrono::system_clock, std::chrono::milliseconds > TimePoint_System_Second
Type alias for system time points with second precision.
Definition TimeTools.hxx:30
std::ostream & operator<<(std::ostream &os, const std::chrono::system_clock::time_point &t)
Overloads the << operator for time_point.
std::chrono::time_point< std::chrono::system_clock, std::chrono::milliseconds > TimePoint_System_Microsecond
Type alias for system time points with microsecond precision.
Definition TimeTools.hxx:25
timeval time_point2Timeval(const std::chrono::time_point< std::chrono::system_clock, Duration > &tp)
Converts a time_point to a timeval.
struct timeval duration2Timeval(const std::chrono::duration< TimeUnit > &dur)
Converts a duration to a timeval.
struct timespec duration2Timespec(const std::chrono::duration< Rep, Period > &dur)
Converts a duration to a timespec.
std::string time_point2String(const std::chrono::time_point< std::chrono::system_clock, Duration > &tp, const std::string &format=DATEFORMAT)
Converts a time_point to a string.
time_t duration2Time_t(const std::chrono::duration< TimeUnit > &duration)
Converts a duration to a time_t.
Definition TimeTools.hxx:78
std::chrono::time_point< std::chrono::system_clock, Duration > time_t2TimePoint(const time_t time)
Converts a time_t to a time_point.
std::chrono::duration< TimeUnit > timeval2Duration(const timeval &tv)
Converts a timeval to a duration.
std::chrono::time_point< std::chrono::system_clock, Duration > timeval2TimePoint(const timeval &tv)
Converts a timeval to a time_point.
std::chrono::duration< Rep, Period > timespec2Duration(const timespec &ts)
Converts a timespec to a duration.
Definition TimeTools.hxx:90
std::chrono::time_point< std::chrono::system_clock, Duration > string2time_point(const std::string &timeString, const std::string &timeStringFormat=DATEFORMAT)
Converts a string to a time_point.
int32_t delay_periodic(int32_t delay_us)
Delays execution periodically.
timespec time_point2Timespec(const std::chrono::time_point< std::chrono::system_clock, Duration > &tp)
Converts a time_point to a timespec.
time_t time_point2Time_t(const std::chrono::time_point< std::chrono::system_clock, Duration > &tp)
Converts a time_point to a time_t.
std::string duration2String(const std::chrono::duration< TimeUnit > &duration, const std::string &format=DATEFORMAT)
Converts a duration to a string.
std::chrono::time_point< std::chrono::system_clock, Duration > timespec2TimePoint(const timespec &ts)
Converts a timespec to a time_point.
std::chrono::duration< TimeUnit > time_t2Duration(const time_t time)
Converts a time_t to a duration.
Definition TimeTools.hxx:67