add HLH_Ref
[HLH_utils.git] / HLH_Time.h
blob5b3248d89f3589d071b48c0e0bc95b73aa5eaa6c
1 /*******************************************************************************
2 * File : HLH_Time.h
3 *
4 * Author : Henry He
5 * Created : 2009-10-8 10:22:07
6 * Description :
7 ******************************************************************************/
9 #ifndef __HLHTIME_INC_20091008_102207_HENRY__
10 #define __HLHTIME_INC_20091008_102207_HENRY__
13 /*******************************************************************************
14 * Desc : Includes Files
15 ******************************************************************************/
16 #include "HLH_utils/typedef.h"
17 #include "HLH_utils/HLH_RoundU32.h"
22 /*******************************************************************************
23 * Desc : Macro Definations
24 ******************************************************************************/
25 #define HLH_NTPTIMEOFFSET 2208988800UL
28 /*******************************************************************************
29 * Desc : Type Definations
30 ******************************************************************************/
33 /*******************************************************************************
34 * Desc : Global Variables
35 ******************************************************************************/
38 /*******************************************************************************
39 * Desc : Functions
40 ******************************************************************************/
44 /******************************************************************************
45 * Desc :
46 * This is a simple wrapper for the most significant word (MSW) and least
47 * significant word (LSW) of an NTP timestamp.
48 ******************************************************************************/
49 class HLH_NTPTime
52 public:
53 /** This constructor creates and instance with MSW \c m and LSW \c l. */
54 HLH_NTPTime(UINT32 unMsw, UINT32 unLsw) {
55 m_unMsw = unMsw;
56 m_unLsw = unLsw;
59 /** Returns the most significant word. */
60 UINT32 GetMSW () const {
61 return m_unMsw;
64 /** Returns the least significant word. */
65 UINT32 GetLSW () const {
66 return m_unLsw;
69 private:
70 UINT32 m_unMsw;
71 UINT32 m_unLsw;
77 /******************************************************************************
78 * Desc :
79 * This class is used to specify wallclock time, delay intervals etc.
80 * It stores a number of seconds and a number of microseconds.
81 ******************************************************************************/
82 class HLH_Time
85 public:
86 /** Creates an HLH_Time instance representing \c dTime,
87 * which is expressed in units of seconds.
89 HLH_Time (double dTime) {
90 SetTime (dTime);
93 /** Creates an instance that corresponds to \c zhnTime.
94 * If the conversion cannot be made, both the seconds and the
95 * microseconds are set to zero.
97 HLH_Time (const HLH_NTPTime &zhnTime) {
98 SetTime (zhnTime);
101 /** Creates an instance corresponding to \c seconds and \c microseconds. */
102 HLH_Time (UINT32 unSecs = 0, UINT32 unMicroSecs = 0) {
103 SetTime (unSecs, unMicroSecs);
106 /** Creates an instance corresponding to \c tvTime. */
107 HLH_Time (const struct timeval &tvTime) {
108 SetTime (tvTime);
112 public:
114 // Set time to dTime
115 void SetTime (double dTime);
117 // Set time to zhnTime
118 void SetTime (const HLH_NTPTime &zhnTime);
120 // Set time to (unSecs, unMicroSecs)
121 void SetTime (UINT32 unSecs, UINT32 unMicroSecs) {
122 m_zhrSecs = unSecs;
123 m_unMicroSecs = unMicroSecs;
126 // Set the time to tvTime
127 void SetTime (const struct timeval &tvTime);
130 public:
132 /** Returns the number of seconds stored in this instance. */
133 UINT32 GetSeconds () const { return (UINT32)m_zhrSecs; }
135 /** Returns the number of microseconds stored in this instance. */
136 UINT32 GetMicroSeconds () const { return m_unMicroSecs; }
138 /** Returns the time stored in this instance, expressed in units of seconds. */
139 double GetDouble () const { return ( ((double)m_zhrSecs) + (((double)m_unMicroSecs)/1000000.0) ); }
141 /** Returns the NTP time corresponding to the time stored in this instance. */
142 HLH_NTPTime GetNTPTime () const;
144 /** Returns the timeval corresponding to the time stored in this instance. */
145 struct timeval GetTimeVal () const;
148 public:
149 /** Returns an HLH_Time instance representing the current wallclock time.
150 * This is expressed as a number of seconds since 00:00:00 UTC, January 1, 1970.
152 static HLH_Time GetCurrentTime ();
154 /** This function waits the amount of time specified in \c delay. */
155 static void WaitX (HLH_Time &zhtDelay);
156 static void Wait (HLH_Time zhtDelay) { WaitX (zhtDelay); }
160 public:
162 HLH_Time operator + (const HLH_Time &zhtTime) const;
163 HLH_Time operator - (const HLH_Time &zhtTime) const;
164 HLH_Time operator * (UINT32 unVal) const;
165 HLH_Time operator / (UINT32 unVal) const;
167 HLH_Time &operator += (const HLH_Time &zhtTime);
168 HLH_Time &operator -= (const HLH_Time &zhtTime);
169 HLH_Time &operator *= (UINT32 unVal);
170 HLH_Time &operator /= (UINT32 unVal);
172 bool operator < (const HLH_Time &zhtTime) const;
173 bool operator > (const HLH_Time &zhtTime) const;
174 bool operator <= (const HLH_Time &zhtTime) const;
175 bool operator >= (const HLH_Time &zhtTime) const;
177 private:
178 HLH_RoundU32 m_zhrSecs;
179 UINT32 m_unMicroSecs;
187 /******************************************************************************
188 * Desc : Member functions
189 ******************************************************************************/
194 /******************************************************************************
195 * Func : HLH_Time::SetTime
196 * Desc : Set time to dTime
197 * Args : dTime Time to be set
198 * Outs : NONE
199 ******************************************************************************/
200 inline void HLH_Time::SetTime (double dTime)
202 double dMicroSecs;
204 m_zhrSecs = (UINT32)dTime;
205 dMicroSecs = ( dTime - ((double)m_zhrSecs) ) * 1000000.0;
206 m_unMicroSecs = (UINT32) dMicroSecs;
210 /******************************************************************************
211 * Func : HLH_Time::SetTime
212 * Desc : Set time to zhnTime
213 * Args : zhnTime Time to be set
214 * Outs : NONE
215 ******************************************************************************/
216 inline void HLH_Time::SetTime (const HLH_NTPTime &zhnTime)
218 double dMicroSecs;
220 if (zhnTime.GetMSW() < HLH_NTPTIMEOFFSET) {
222 m_zhrSecs = 0;
223 m_unMicroSecs = 0;
225 } else {
227 m_zhrSecs = zhnTime.GetMSW () - HLH_NTPTIMEOFFSET;
228 dMicroSecs = (double) zhnTime.GetLSW ();
229 dMicroSecs /= ( 65536.0 * 65536.0 );
230 dMicroSecs *= 1000000.0;
231 m_unMicroSecs = (UINT32) dMicroSecs;
238 /******************************************************************************
239 * Func : HLH_Time::SetTime
240 * Desc : Set the time to tvTime
241 * Args : tvTime Time to be set
242 * Outs : NONE
243 ******************************************************************************/
244 inline void HLH_Time::SetTime (const struct timeval &tvTime)
246 m_zhrSecs = tvTime.tv_sec;
247 m_unMicroSecs = tvTime.tv_usec;
252 /******************************************************************************
253 * Func : HLH_Time::GetNTPTime
254 * Desc : Get time in NTP format
255 * Args : NONE
256 * Outs : return time in NTP format
257 ******************************************************************************/
258 inline HLH_NTPTime HLH_Time::GetNTPTime () const
260 UINT32 unMsw;
261 UINT32 unLsw;
262 double dLsw;
264 unMsw = (UINT32)m_zhrSecs + HLH_NTPTIMEOFFSET;
265 dLsw = m_unMicroSecs / 1000000.0;
266 dLsw *= (65536.0 * 65536.0);
267 unLsw = (UINT32) dLsw;
269 return HLH_NTPTime (unMsw, unLsw);
273 /******************************************************************************
274 * Func : HLH_Time::GetTimeVal
275 * Desc : Returns the timeval corresponding to the time stored in this instance.
276 * Args : NONE
277 * Outs : Returns the timeval corresponding to the time stored in this instance.
278 ******************************************************************************/
279 inline struct timeval HLH_Time::GetTimeVal () const
281 struct timeval tvTime;
283 tvTime.tv_sec = (UINT32) m_zhrSecs;
284 tvTime.tv_usec = m_unMicroSecs;
286 return tvTime;
294 /******************************************************************************
295 * Func : GetCurrentTime
296 * Desc : Get current time
297 * Args : NONE
298 * Outs : Return current time
299 ******************************************************************************/
300 inline HLH_Time HLH_Time::GetCurrentTime ()
302 struct timeval tvTime;
304 gettimeofday (&tvTime, 0);
306 return HLH_Time (tvTime);
309 /******************************************************************************
310 * Func : Wait
311 * Desc : Wait for 'zhtDelay' time
312 * Args : zhtDelay Time to wait
313 * Outs : NONE
314 ******************************************************************************/
315 inline void HLH_Time::WaitX (HLH_Time &zhtDelay)
317 struct timespec tsReq;
318 struct timespec tsRem;
320 tsReq.tv_sec = (UINT32) zhtDelay.m_zhrSecs;
321 tsReq.tv_nsec = zhtDelay.m_unMicroSecs * 1000;
323 // Sleep for tsReq
324 nanosleep ( &tsReq, &tsRem );
326 // Set remained time
327 zhtDelay.SetTime ( tsRem.tv_sec, tsRem.tv_nsec / 1000 );
336 /******************************************************************************
337 * Desc : Operators
338 ******************************************************************************/
341 inline HLH_Time HLH_Time::operator + (const HLH_Time &zhtTime) const
343 HLH_Time zhtResult;
345 zhtResult.m_zhrSecs = m_zhrSecs + zhtTime.m_zhrSecs;
346 zhtResult.m_unMicroSecs = m_unMicroSecs + zhtTime.m_unMicroSecs;
348 if (zhtResult.m_unMicroSecs > 1000000) {
349 zhtResult.m_unMicroSecs -= 1000000;
350 zhtResult.m_zhrSecs ++;
353 return zhtResult;
357 inline HLH_Time HLH_Time::operator - (const HLH_Time &zhtTime) const
359 HLH_Time zhtResult;
361 zhtResult.m_zhrSecs = m_zhrSecs - zhtTime.m_zhrSecs;
362 zhtResult.m_unMicroSecs = m_unMicroSecs;
364 if (zhtResult.m_unMicroSecs < zhtTime.m_unMicroSecs)
366 zhtResult.m_zhrSecs --;
367 zhtResult.m_unMicroSecs += 1000000;
369 zhtResult.m_unMicroSecs -= zhtTime.m_unMicroSecs;
371 return zhtResult;
374 inline HLH_Time HLH_Time::operator * (UINT32 unVal) const
376 HLH_Time zhtResult;
377 UINT32 unMicroSecs;
379 unMicroSecs = m_unMicroSecs * unVal;
381 zhtResult.m_zhrSecs = ((UINT32)m_zhrSecs) * unVal + unMicroSecs / 1000000;
382 zhtResult.m_unMicroSecs = unMicroSecs % 1000000;
384 return zhtResult;
388 inline HLH_Time HLH_Time::operator / (UINT32 unVal) const
390 HLH_Time zhtResult;
391 HLH_RoundU32 zhrSecs;
392 UINT32 unMicroSecs;
394 zhtResult.m_zhrSecs = (UINT32)m_zhrSecs / unVal;
396 unMicroSecs = ( (UINT32)m_zhrSecs % unVal ) * 1000000 + m_unMicroSecs;
397 zhtResult.m_unMicroSecs = unMicroSecs / unVal;
399 return zhtResult;
404 inline HLH_Time & HLH_Time::operator += (const HLH_Time &zhtTime)
406 m_zhrSecs += zhtTime.m_zhrSecs;
407 m_unMicroSecs += zhtTime.m_unMicroSecs;
408 if (m_unMicroSecs >= 1000000) {
409 m_zhrSecs ++;
410 m_unMicroSecs -= 1000000;
413 return *this;
417 inline HLH_Time & HLH_Time::operator -= (const HLH_Time &zhtTime)
419 m_zhrSecs -= zhtTime.m_zhrSecs;
420 if (zhtTime.m_unMicroSecs > m_unMicroSecs) {
421 m_zhrSecs--;
422 m_unMicroSecs += 1000000;
424 m_unMicroSecs -= zhtTime.m_unMicroSecs;
426 return *this;
430 inline HLH_Time & HLH_Time::operator *= (UINT32 unVal)
432 UINT32 unMicroSecs;
434 unMicroSecs = m_unMicroSecs * unVal;
435 m_zhrSecs = (UINT32)m_zhrSecs * unVal + unMicroSecs / 1000000;
436 m_unMicroSecs = unMicroSecs % 1000000;
438 return *this;
442 inline HLH_Time & HLH_Time::operator /= (UINT32 unVal)
444 HLH_RoundU32 zhrSecs;
445 UINT32 unMicroSecs;
448 m_zhrSecs /= unVal;
450 unMicroSecs = ( (UINT32)m_zhrSecs % unVal) * 1000000 + m_unMicroSecs;
451 m_unMicroSecs = unMicroSecs / unVal;
453 return *this;
460 inline bool HLH_Time::operator < (const HLH_Time &zhtTime) const
462 if (m_zhrSecs < zhtTime.m_zhrSecs)
463 return true;
464 if (m_zhrSecs > zhtTime.m_zhrSecs)
465 return false;
466 if (m_unMicroSecs < zhtTime.m_unMicroSecs)
467 return true;
468 return false;
471 inline bool HLH_Time::operator > (const HLH_Time &zhtTime) const
473 if (m_zhrSecs > zhtTime.m_zhrSecs)
474 return true;
475 if (m_zhrSecs < zhtTime.m_zhrSecs)
476 return false;
477 if (m_unMicroSecs > zhtTime.m_unMicroSecs)
478 return true;
479 return false;
482 inline bool HLH_Time::operator <= (const HLH_Time &zhtTime) const
484 if (m_zhrSecs < zhtTime.m_zhrSecs)
485 return true;
486 if (m_zhrSecs > zhtTime.m_zhrSecs)
487 return false;
488 if (m_unMicroSecs <= zhtTime.m_unMicroSecs)
489 return true;
490 return false;
494 inline bool HLH_Time::operator >= (const HLH_Time &zhtTime) const
496 if (m_zhrSecs > zhtTime.m_zhrSecs)
497 return true;
498 if (m_zhrSecs < zhtTime.m_zhrSecs)
499 return false;
500 if (m_unMicroSecs >= zhtTime.m_unMicroSecs)
501 return true;
502 return false;
509 #endif /* __HLHTIME_INC_20091008_102207_HENRY__ */