Panda3D
time_clock.h
1 #ifndef __Time_H__
2 #define __Time_H__
3 
4 #include <stdio.h>
5 
6 class Time_Span;
7 
8 /**
9  * This class is to provide a consistant interface and storage to clock time
10  * .. Epoch based time to the second
11  *
12  * jan-2000 .. rhh changing all time to use sub second timing...
13  */
14 class Time_Clock {
15  friend class Time_Span;
16 
17 public:
18  // Constructors
19  static Time_Clock GetCurrentTime();
20  void ToCurrentTime();
21  inline Time_Clock(const timeval &in_mytime) {
22  _my_time = in_mytime;
23  }
24  Time_Clock();
25  Time_Clock(time_t time);
26  Time_Clock(long secs, long usecs);
27  Time_Clock(int nYear, int nMonth, int nDay, int nHour, int nMin, int nSec, long microseconds = 0, int nDST = -1);
28  Time_Clock(const Time_Clock& timeSrc);
29 
30  inline const Time_Clock &operator=(const Time_Clock& timeSrc);
31  inline const Time_Clock &operator=(time_t t);
32 
33  // Attributes
34  struct tm *GetGmtTm(struct tm *ptm) const;
35  struct tm *GetLocalTm(struct tm *ptm) const;
36 
37  time_t GetTime() const;
38  int GetYear() const;
39  int GetMonth() const; // month of year (1 = Jan)
40  int GetDay() const; // day of month
41  int GetHour() const;
42  int GetMinute() const;
43  int GetSecond() const;
44  int GetDayOfWeek() const; // 1=Sun, 2=Mon, ..., 7=Sat
45 
46  void Set(int nYear, int nMonth, int nDay, int nHour, int nMin, int nSec, long microseconds = 0, int nDST = -1);
47 
48  // Operations time math
49  const Time_Clock& operator+=(const Time_Span &Time_Span);
50  const Time_Clock& operator-=(const Time_Span &Time_Span);
51  bool operator==(const Time_Clock &time) const;
52  bool operator!=(const Time_Clock &time) const;
53  bool operator<(const Time_Clock &time) const;
54  bool operator>(const Time_Clock &time) const;
55  bool operator<=(const Time_Clock &time) const;
56  bool operator>=(const Time_Clock &time) const;
57 
58  inline time_t GetTime_t() {
59  return _my_time.tv_sec;
60  }
61  inline long GetUsecPart() {
62  return _my_time.tv_usec;
63  }
64 
65  // formatting using "C" strftime
66  std::string Format(const char *pFormat) const;
67  std::string FormatGmt(const char *pFormat) const;
68 
69  const timeval &GetTval() {
70  return _my_time;
71  }
72  const timeval &GetTval() const {
73  return _my_time;
74  }
75 
76 private:
77  struct timeval _my_time;
78 };
79 
80 /**
81  * Construction from parts
82  */
83 inline Time_Clock::
84 Time_Clock(int nYear, int nMonth, int nDay, int nHour, int nMin, int nSec, long microseconds, int nDST) {
85  struct tm atm;
86  atm.tm_sec = nSec;
87  atm.tm_min = nMin;
88  atm.tm_hour = nHour;
89  assert(nDay >= 1 && nDay <= 31);
90  atm.tm_mday = nDay;
91  assert(nMonth >= 1 && nMonth <= 12);
92  atm.tm_mon = nMonth - 1; // tm_mon is 0 based
93  assert(nYear >= 1900);
94  atm.tm_year = nYear - 1900; // tm_year is 1900 based
95  atm.tm_isdst = nDST;
96  _my_time.tv_sec = (long)mktime(&atm);
97  assert(_my_time.tv_sec != -1); // indicates an illegal input time
98  _my_time.tv_usec = microseconds;
99  assert(_my_time.tv_usec < 1000000);
100 }
101 
102 /**
103  *
104  */
105 inline void Time_Clock::
106 Set(int nYear, int nMonth, int nDay, int nHour, int nMin, int nSec, long microseconds , int nDST) {
107  struct tm atm;
108  atm.tm_sec = nSec;
109  atm.tm_min = nMin;
110  atm.tm_hour = nHour;
111  assert(nDay >= 1 && nDay <= 31);
112  atm.tm_mday = nDay;
113  assert(nMonth >= 1 && nMonth <= 12);
114  atm.tm_mon = nMonth - 1; // tm_mon is 0 based
115  assert(nYear >= 1900);
116  atm.tm_year = nYear - 1900; // tm_year is 1900 based
117  atm.tm_isdst = nDST;
118  _my_time.tv_sec = (long)mktime(&atm);
119  assert(_my_time.tv_sec != -1); // indicates an illegal input time
120  _my_time.tv_usec = microseconds;
121  assert(_my_time.tv_usec < 1000000);
122 }
123 
124 /**
125  * The Default no param constructor.. Will set time to current system time
126  */
129  return Time_Clock();
130 }
131 
132 /**
133  *
134  */
135 inline Time_Clock::
136 Time_Clock() {
137  gettimeofday(&_my_time, nullptr);
138 }
139 
140 /**
141  * Load this object with the current OS time
142  */
143 inline void Time_Clock::
145  gettimeofday(&_my_time, nullptr);
146 }
147 
148 /**
149  * Access the stored time and converts to a struct tm format If storage
150  * location is specified then it will stor information in the provided buffer
151  * else it will use the library's internal buffer space
152  */
153 inline struct tm *Time_Clock::
154 GetGmtTm(struct tm *ptm) const {
155  nassertr(ptm != nullptr, nullptr);
156 #ifdef _WIN32
157  return (gmtime_s(ptm, (const time_t *)&_my_time.tv_sec) == 0) ? ptm : nullptr;
158 #else
159  return gmtime_r((const time_t *)&_my_time.tv_sec, ptm);
160 #endif
161 }
162 
163 /**
164  * Gets The local time in a tm structre from the internal time value
165  */
166 inline struct tm *Time_Clock::
167 GetLocalTm(struct tm *ptm) const {
168  nassertr(ptm != nullptr, nullptr);
169 #ifdef _WIN32
170  return (localtime_s(ptm, (const time_t *)&_my_time.tv_sec) == 0) ? ptm : nullptr;
171 #else
172  return localtime_r((const time_t *)&_my_time.tv_sec, ptm);
173 #endif
174 }
175 // String formatting Verifies will fail if the needed buffer size is too large
176 #define maxTimeBufferSize 4096
177 
178 /**
179  * Used to allow access to the "C" library strftime functions..
180  */
181 inline std::string Time_Clock::
182 Format(const char *pFormat) const {
183  char szBuffer[maxTimeBufferSize];
184  char ch, ch1;
185  char *pch = szBuffer;
186 
187  while ((ch = *pFormat++) != '\0') {
188  assert(pch < &szBuffer[maxTimeBufferSize]);
189  if (ch == '%') {
190  switch (ch1 = *pFormat++) {
191  default:
192  *pch++ = ch;
193  *pch++ = ch1;
194  break;
195  case 'N':
196 #ifdef _WIN32
197  pch += sprintf_s(pch, maxTimeBufferSize, "%03ld", (long)(_my_time.tv_usec / 1000));
198 #else
199  pch += snprintf(pch, maxTimeBufferSize, "%03ld", (long)(_my_time.tv_usec / 1000));
200 #endif
201  break;
202  }
203  } else {
204  *pch++ = ch;
205  }
206  }
207 
208  *pch = '\0';
209 
210  char szBuffer1[maxTimeBufferSize];
211 
212  struct tm tmTemp;
213  if (GetLocalTm(&tmTemp) == nullptr ||
214  !strftime(szBuffer1, sizeof(szBuffer1), szBuffer, &tmTemp)) {
215  szBuffer1[0] = '\0';
216  }
217  return std::string(szBuffer1);
218 }
219 
220 /**
221  * A Wraper to size_t strftime( char *strDest, size_t maxsize, const char
222  * *format, const struct tm *timeptr );
223  *
224  */
225 inline std::string Time_Clock::
226 FormatGmt(const char *pFormat) const {
227  char szBuffer[maxTimeBufferSize];
228  char ch, ch1;
229  char *pch = szBuffer;
230 
231  while ((ch = *pFormat++) != '\0') {
232  assert(pch < &szBuffer[maxTimeBufferSize]);
233  if (ch == '%') {
234  switch (ch1 = *pFormat++) {
235  default:
236  *pch++ = ch;
237  *pch++ = ch1;
238  break;
239  case 'N':
240 #ifdef _WIN32
241  pch += sprintf_s(pch, maxTimeBufferSize, "%03ld", (long)(_my_time.tv_usec / 1000));
242 #else
243  pch += snprintf(pch, maxTimeBufferSize, "%03ld", (long)(_my_time.tv_usec / 1000));
244 #endif
245  break;
246  }
247  } else {
248  *pch++ = ch;
249  }
250  }
251  *pch = '\0';
252 
253  char szBuffer1[maxTimeBufferSize];
254 
255  struct tm tmTemp;
256  if (GetGmtTm(&tmTemp) == nullptr ||
257  !strftime(szBuffer1, sizeof(szBuffer1), szBuffer, &tmTemp)) {
258  szBuffer1[0] = '\0';
259  }
260  return std::string(szBuffer1);
261 }
262 
263 /**
264  * The Constructor that take a time_t objext
265  */
266 inline Time_Clock::
267 Time_Clock(time_t time) {
268  _my_time.tv_sec = (long)time;
269  _my_time.tv_usec = 0;
270 }
271 
272 /**
273  * Constructor that takes in sec and usecs..
274  */
275 inline Time_Clock::
276 Time_Clock(long secs, long usecs) {
277  _my_time.tv_sec = secs;
278  _my_time.tv_usec = usecs;
279  NormalizeTime(_my_time);
280 }
281 
282 /**
283  * yet another constructor
284  */
285 inline Time_Clock::
286 Time_Clock(const Time_Clock& timeSrc) {
287  _my_time.tv_sec = timeSrc._my_time.tv_sec;
288  _my_time.tv_usec = timeSrc._my_time.tv_usec;
289 }
290 
291 /**
292  * .. is time equal
293  */
294 inline bool Time_Clock::
295 operator==(const Time_Clock &time) const {
296  return ((_my_time.tv_sec == time._my_time.tv_sec) && (_my_time.tv_usec == time._my_time.tv_usec));
297 }
298 
299 /**
300  * .is time !=
301  */
302 inline bool Time_Clock::
303 operator!=(const Time_Clock &time) const {
304  return ((_my_time.tv_sec != time._my_time.tv_sec) || (_my_time.tv_usec != time._my_time.tv_usec));
305 }
306 
307 /**
308  *
309  */
310 inline bool Time_Clock::
311 operator<(const Time_Clock &time) const {
312  return ((_my_time.tv_sec < time._my_time.tv_sec) ||
313  ((_my_time.tv_sec == time._my_time.tv_sec) && (_my_time.tv_usec < time._my_time.tv_usec)));
314 }
315 
316 /**
317  *
318  */
319 inline bool Time_Clock::
320 operator>(const Time_Clock &time) const {
321  return ((_my_time.tv_sec > time._my_time.tv_sec) ||
322  ((_my_time.tv_sec == time._my_time.tv_sec) && (_my_time.tv_usec > time._my_time.tv_usec)));
323 }
324 
325 /**
326  *
327  */
328 inline bool Time_Clock::
329 operator<=(const Time_Clock &time) const {
330  return ((_my_time.tv_sec < time._my_time.tv_sec) ||
331  ((_my_time.tv_sec == time._my_time.tv_sec) && (_my_time.tv_usec <= time._my_time.tv_usec)));
332 }
333 
334 /**
335  *
336  */
337 inline bool Time_Clock::
338 operator>=(const Time_Clock &time) const {
339  return ((_my_time.tv_sec > time._my_time.tv_sec) ||
340  ((_my_time.tv_sec == time._my_time.tv_sec) && (_my_time.tv_usec >= time._my_time.tv_usec)));
341 }
342 
343 /**
344  *
345  */
346 inline const Time_Clock& Time_Clock::
347 operator=(const Time_Clock& timeSrc) {
348  if (&timeSrc == this) {
349  return *this;
350  }
351 
352  _my_time = timeSrc._my_time;
353  return *this;
354 }
355 
356 /**
357  *
358  */
359 inline const Time_Clock& Time_Clock::
360 operator=(time_t t) {
361  _my_time.tv_sec = (long)t;
362  _my_time.tv_usec = 0;
363  return *this;
364 }
365 
366 /**
367  *
368  */
369 inline time_t Time_Clock::
370 GetTime() const {
371  return _my_time.tv_sec;
372 }
373 
374 /**
375  *
376  */
377 inline int Time_Clock::
378 GetYear() const {
379  struct tm atm;
380  return (GetLocalTm(&atm)->tm_year) + 1900;
381 }
382 
383 /**
384  *
385  */
386 inline int Time_Clock::
387 GetMonth() const {
388  struct tm atm;
389  return GetLocalTm(&atm)->tm_mon + 1;
390 }
391 
392 /**
393  *
394  */
395 inline int Time_Clock::
396 GetDay() const {
397  struct tm atm;
398  return GetLocalTm(&atm)->tm_mday;
399 }
400 
401 /**
402  *
403  */
404 inline int Time_Clock::
405 GetHour() const {
406  struct tm atm;
407  return GetLocalTm(&atm)->tm_hour;
408 }
409 
410 /**
411  *
412  */
413 inline int Time_Clock::
414 GetMinute() const {
415  struct tm atm;
416  return GetLocalTm(&atm)->tm_min;
417 }
418 
419 /**
420  *
421  */
422 inline int Time_Clock::
423 GetSecond() const {
424  struct tm atm;
425  return GetLocalTm(&atm)->tm_sec;
426 }
427 
428 /**
429  *
430  */
431 inline int Time_Clock::
432 GetDayOfWeek() const {
433  struct tm atm;
434  return GetLocalTm(&atm)->tm_wday + 1;
435 }
436 
437 #endif //__Time_H__
std::string Format(const char *pFormat) const
Used to allow access to the "C" library strftime functions.
Definition: time_clock.h:182
This class is to provide a consistant interface and storage to clock time
Definition: time_clock.h:14
struct tm * GetGmtTm(struct tm *ptm) const
Access the stored time and converts to a struct tm format If storage location is specified then it wi...
Definition: time_clock.h:154
bool operator==(const Time_Clock &time) const
Definition: time_clock.h:295
bool operator!=(const Time_Clock &time) const
.is time !=
Definition: time_clock.h:303
std::string FormatGmt(const char *pFormat) const
A Wraper to size_t strftime( char *strDest, size_t maxsize, const char *format, const struct tm *time...
Definition: time_clock.h:226
void ToCurrentTime()
Load this object with the current OS time.
Definition: time_clock.h:144
struct tm * GetLocalTm(struct tm *ptm) const
Gets The local time in a tm structre from the internal time value.
Definition: time_clock.h:167
static Time_Clock GetCurrentTime()
The Default no param constructor.
Definition: time_clock.h:128