time.cpp

00001
00002 /***************************************************************************
00003  *  time.c - A time class
00004  *
00005  *  Created: Wed Jun 06 16:50:11 2007
00006  *  Copyright  2007       Daniel Beck
00007  *             2007-2009  Tim Niemueller [www.niemueller.de]
00008  *
00009  ****************************************************************************/
00010
00011 /*  This program is free software; you can redistribute it and/or modify
00012  *  it under the terms of the GNU General Public License as published by
00013  *  the Free Software Foundation; either version 2 of the License, or
00014  *  (at your option) any later version. A runtime exception applies to
00015  *  this software (see LICENSE.GPL_WRE file mentioned below for details).
00016  *
00017  *  This program is distributed in the hope that it will be useful,
00018  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00019  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020  *  GNU Library General Public License for more details.
00021  *
00022  *  Read the full text in the LICENSE.GPL_WRE file in the doc directory.
00023  */
00024
00025 #include <utils/time/time.h>
00026 #include <utils/time/clock.h>
00027
00028 #include <core/exception.h>
00029
00030 #include <time.h>
00031 #include <cmath>
00032 #include <cstdio>
00033 #include <cstdlib>
00034 #include <cstring>
00035 #include <unistd.h>
00036
00037 namespace fawkes {
00038 #if 0 /* just to make Emacs auto-indent happy */
00039 }
00040 #endif
00041 
00042 /** @class Time <utils/time/time.h>
00043  * A class for handling time.
00044  * @author Daniel Beck
00045  * @author Tim Niemueller
00046  */
00047 
00048 /** Maximum size of string returned by str() and the minimum size
00049  * of the string passwd to str_r(). */
00050 // as recommened in asctime_r() docs
00051 const unsigned int Time::TIMESTR_SIZE = 26;
00052
00053 
00054 /** Constructor.
00055  * Sets time to the current time.
00056  */
00057 Time::Time()
00058 {
00059   __clock = Clock::instance();
00060   __clock->get_time(&__time);
00061   __timestr = NULL;
00062 }
00063
00064 
00065 /** Constructor.
00066  * Sets time to the given time.
00067  * @param tv the Time object is initialized with the time given in this timeval
00068  */
00069 Time::Time(const timeval* tv)
00070 {
00071   __time.tv_sec = tv->tv_sec;
00072   __time.tv_usec = tv->tv_usec;
00073   __clock = Clock::instance();
00074   __timestr = NULL;
00075 }
00076
00077 
00078 /** Constructor.
00079  * Sets time to the given time. Basically the same as setting from a timeval struct
00080  * but the components are given separately.
00081  * @param sec time in seconds since the epoch (or time range)
00082  * @param usec fractions in microseconds added to sec
00083  * @param clock optional clock to use, if NULL Clock::instance() will be used
00084  */
00085 Time::Time(long sec, long usec, Clock *clock)
00086 {
00087   __time.tv_sec  = sec;
00088   __time.tv_usec = usec;
00089   if (clock) {
00090     __clock = clock;
00091   } else {
00092     __clock = Clock::instance();
00093   }
00094   __timestr = NULL;
00095 }
00096
00097 
00098 /** Constructor.
00099  * Sets time to given number of ms, use for time range.
00100  * @param ms the Time object is initialized to the time given in milli-seconds
00101  */
00102 Time::Time(long ms)
00103 {
00104   time_t sec = (time_t) (ms / 1000.0);
00105   suseconds_t usec =  (ms % 1000) * 1000;
00106
00107   __time.tv_sec = sec;
00108   __time.tv_usec = usec;
00109   __clock = Clock::instance();
00110   __timestr = NULL;
00111 }
00112
00113 
00114 /** Constructor.
00115  * Sets time to given number of ms, use for time range.
00116  * @param s the Time object is initialized to the time given in seconds
00117  */
00118 Time::Time(float s)
00119 {
00120   time_t sec = (time_t) s;
00121   suseconds_t usec = (suseconds_t)roundf((s - sec) * 1000000.f);
00122
00123   __time.tv_sec = sec;
00124   __time.tv_usec = usec;
00125   __clock = Clock::instance();
00126   __timestr = NULL;
00127 }
00128
00129 
00130 /** Constructor.
00131  * This constructor uses the supplied clock for setting the time. The
00132  * time is set to the current time.
00133  * @param clock clock
00134  */
00135 Time::Time(Clock *clock)
00136 {
00137   this->__clock = clock;
00138   __clock->get_time(&__time);
00139   __timestr = NULL;
00140 }
00141
00142 
00143 /** Copy constructor.
00144  * @param t time to copy
00145  */
00146 Time::Time(const Time &t)
00147 {
00148   __time.tv_sec  = t.__time.tv_sec;
00149   __time.tv_usec = t.__time.tv_usec;
00150   __clock        = t.__clock;
00151   if (t.__timestr) {
00152     __timestr = (char *)malloc(TIMESTR_SIZE);
00153     strncpy(__timestr, t.__timestr, TIMESTR_SIZE);
00154   } else {
00155     __timestr = NULL;
00156   }
00157 }
00158
00159 
00160 /** Destructor. */
00161 Time::~Time()
00162 {
00163   if (__timestr)  free(__timestr);
00164 }
00165
00166 
00167 /** Convet time to seconds.
00168  * Convert the stored time in a floating point number representing the
00169  * number of seconds. For a time the integral part is the number of seconds
00170  * since the epoch, for ranges you get the value as a float second.
00171  * @return the time in seconds
00172  */
00173 float
00174 Time::in_sec() const
00175 {
00176   return (__time.tv_sec + __time.tv_usec / 1000000.f);
00177 }
00178
00179 
00180 /** Convert the stored time into milli-seconds.
00181  * @return the time in milli-seconds
00182  */
00183 long
00184 Time::in_msec() const
00185 {
00186   return (__time.tv_sec * 1000 + (long) (__time.tv_usec / 1000));
00187 }
00188
00189 
00190 /** Convert the stored time into micro-seconds.
00191  * @return the time in micro-seconds
00192  */
00193 long
00194 Time::in_usec() const
00195 {
00196   return (__time.tv_sec * 1000000 + __time.tv_usec);
00197 }
00198
00199 
00200 /** Obtain the timeval where the time is stored.
00201  * @return a const pointer to the timeval where the time is stored
00202  */
00203 const timeval *
00204 Time::get_timeval() const
00205 {
00206   return &__time;
00207 }
00208
00209 
00210 /** Sets the time.
00211  * @param tv set the time to this value
00212  */
00213 void
00214 Time::set_time(const timeval* tv)
00215 {
00216   __time.tv_sec = tv->tv_sec;
00217   __time.tv_usec = tv->tv_usec;
00218 }
00219
00220 
00221 /** Sets the time.
00222  * @param sec seconds part of the time
00223  * @param usec microseconds part of the time
00224  */
00225 void
00226 Time::set_time(long int sec, long int usec)
00227 {
00228   __time.tv_sec  = sec;
00229   __time.tv_usec = usec;
00230 }
00231
00232 
00233 /** Sets the time.
00234  * @param ms set the time to this value
00235  */
00236 void
00237 Time::set_time(long ms)
00238 {
00239   __time.tv_sec  = (time_t) (ms / 1000.0);
00240   __time.tv_usec = (ms % 1000) * 1000;
00241 }
00242
00243 
00244 /** Sets the time.
00245  * @param s set the time to this value
00246  */
00247 void
00248 Time::set_time(float s)
00249 {
00250   __time.tv_sec  = (time_t)floor(s);
00251   __time.tv_usec = (suseconds_t)(s - __time.tv_sec) * 1000000;
00252 }
00253 
00254 /** Set time to given time.
00255  * this is equivalent to operator+, but can be used in situations where
00256  * the operator cannot be used (for example in Lua).
00257  * @param t time to set to
00258  */
00259 void
00260 Time::set_time(const Time &t)
00261 {
00262   *this = t;
00263 }
00264
00265 
00266 /** Set time to given time.
00267  * @param t time to set to
00268  */
00269 void
00270 Time::set_time(const Time *t)
00271 {
00272   __time.tv_sec  = t->__time.tv_sec;
00273   __time.tv_usec = t->__time.tv_usec;
00274 }
00275
00276 
00277 /** Add seconds.
00278  * The effect is equivalent to operator+=(const float sec), but this
00279  * can be used when the operator is not available (i.e. wrapper languages)
00280  * and it does not return itself.
00281  * @param seconds time in seconds to add
00282  */
00283 void
00284 Time::add(float seconds)
00285 {
00286   *this += seconds;
00287 }
00288 
00289 /** Operator that adds times.
00290  * @param t the other summand
00291  * @return the sum
00292  */
00293 Time
00294 Time::operator+(const Time& t) const
00295 {
00296   Time ret;
00297   if (__time.tv_usec + t.__time.tv_usec >= 1000000)
00298   {
00299     ret.__time.tv_usec = __time.tv_usec + t.__time.tv_usec - 1000000;
00300     ret.__time.tv_sec = __time.tv_sec + t.__time.tv_sec + 1;
00301   }
00302   else
00303   {
00304     ret.__time.tv_usec = __time.tv_usec + t.__time.tv_usec;
00305     ret.__time.tv_sec = __time.tv_sec + t.__time.tv_sec;
00306   }
00307
00308   return ret;
00309 }
00310
00311 
00312 /** Operator that adds times.
00313  * @param t the other summand
00314  * @return the sum
00315  */
00316 Time
00317 Time::operator+(const Time* t) const
00318 {
00319   return *this + *t;
00320 }
00321
00322 
00323 /** Operator that adds times.
00324  * @param sec number of seconds to add
00325  * @return the sum
00326  */
00327 Time
00328 Time::operator+(const float sec) const
00329 {
00330   Time ret;
00331   time_t sec_only = (time_t)floor(sec);
00332   suseconds_t usec_only = (suseconds_t)roundf((sec - sec_only) * 1000000);
00333   if ((__time.tv_usec + usec_only) >= 1000000)
00334   {
00335     ret.__time.tv_usec = __time.tv_usec + usec_only - 1000000;
00336     ret.__time.tv_sec = __time.tv_sec + sec_only + 1;
00337   }
00338   else
00339   {
00340     ret.__time.tv_usec = __time.tv_usec + usec_only;
00341     ret.__time.tv_sec = __time.tv_sec + sec_only;
00342   }
00343
00344   return ret;
00345 }
00346
00347 
00348 /** Operator that substracts one Time from another.
00349  * @param t the Time that is substracted
00350  * @return the difference
00351  */
00352 Time
00353 Time::operator-(const Time& t) const
00354 {
00355   Time ret;
00356   if (__time.tv_usec < t.__time.tv_usec)
00357   {
00358     ret.__time.tv_usec = 1000000 + __time.tv_usec - t.__time.tv_usec;
00359     ret.__time.tv_sec = __time.tv_sec - t.__time.tv_sec - 1;
00360   }
00361   else
00362   {
00363     ret.__time.tv_usec = __time.tv_usec - t.__time.tv_usec;
00364     ret.__time.tv_sec = __time.tv_sec - t.__time.tv_sec;
00365   }
00366
00367   return ret;
00368 }
00369
00370 
00371 /** Operator that substracts one Time from another.
00372  * @param t the Time that is substracted
00373  * @return the difference
00374  */
00375 float
00376 Time::operator-(const Time* t) const
00377 {
00378   return time_diff_sec(__time, t->__time);
00379 }
00380
00381 
00382 /** += operator
00383  * @param t the other time
00384  * @return reference to this instance
00385  */
00386 Time &
00387 Time::operator+=(const Time& t)
00388 {
00389   if (__time.tv_usec + t.__time.tv_usec >= 1000000)
00390   {
00391     __time.tv_usec += t.__time.tv_usec - 1000000;
00392     __time.tv_sec  += t.__time.tv_sec + 1;
00393   }
00394   else
00395   {
00396     __time.tv_usec += t.__time.tv_usec;
00397     __time.tv_sec  += t.__time.tv_sec;
00398   }
00399
00400   return *this;
00401 }
00402
00403 
00404 /** += operator
00405  * @param usec microseconds to add
00406  * @return reference to this instance
00407  */
00408 Time &
00409 Time::operator+=(const long int usec)
00410 {
00411   if ( __time.tv_usec + usec >= 1000000 )
00412   {
00413     //usec + __time.tv_usec might be more than 1 second
00414     long int tmp_usec = __time.tv_usec + usec;
00415     __time.tv_usec = tmp_usec % 1000000;
00416     __time.tv_sec  += tmp_usec / 1000000;
00417   }
00418   else
00419   {
00420     __time.tv_usec += usec;
00421   }
00422
00423   return *this;
00424 }
00425
00426 
00427 /** += operator for float seconds
00428  * @param sec number of seconds to add
00429  * @return the sum
00430  */
00431 Time &
00432 Time::operator+=(const float sec)
00433 {
00434   time_t sec_only = (time_t)floor(sec);
00435   suseconds_t usec_only = (suseconds_t)roundf((sec - sec_only) * 1000000);
00436   if ((__time.tv_usec + usec_only) >= 1000000)
00437   {
00438     __time.tv_usec += usec_only - 1000000;
00439     __time.tv_sec  += sec_only + 1;
00440   }
00441   else
00442   {
00443     __time.tv_usec += usec_only;
00444     __time.tv_sec  += sec_only;
00445   }
00446
00447   return *this;
00448 }
00449
00450 
00451 /** -= operator.
00452  * @param t the other time
00453  * @return reference to this instance
00454  */
00455 Time &
00456 Time::operator-=(const Time& t)
00457 {
00458   *this = *this - t;
00459   return *this;
00460 }
00461
00462 
00463 /** Assign operator.
00464  * @param t time to assign to this instance
00465  * @return reference to this instance
00466  */
00467 Time &
00468 Time::operator=(const Time &t)
00469 {
00470   __time.tv_sec  = t.__time.tv_sec;
00471   __time.tv_usec = t.__time.tv_usec;
00472   __clock        = t.__clock;
00473   return *this;
00474 }
00475
00476 
00477 /** Set this time to the current time.
00478  * @return reference to this instance
00479  */
00480 Time &
00481 Time::stamp()
00482 {
00483   if ( NULL != __clock ) {
00484     __clock->get_time(&__time);
00485   } else {
00486     throw Exception("Clock not set, cannot stamp time");
00487   }
00488   return *this;
00489 }
00490
00491 
00492 /** Set this time to the current system time.
00493  * This bypasses any possibly registered time source. Use with care and only
00494  * where you really need the system time.
00495  * @return reference to this instance
00496  */
00497 Time &
00498 Time::stamp_systime()
00499 {
00500   if ( NULL != __clock ) {
00501     __clock->get_systime(&__time);
00502   } else {
00503     throw Exception("Clock not set, cannot stamp time (systime)");
00504   }
00505   return *this;
00506 }
00507
00508 
00509 /** Wait (sleep) for this time.
00510  * This waits for as much time as this instance provides. Note that you have to
00511  * make sure that you call this on a sensible time range. You probably do not want
00512  * to wait for almost 40 years when passing a time point...
00513  */
00514 void
00515 Time::wait()
00516 {
00517   Time until, now;
00518   until += *this;
00519
00520   // we want to release run status at least shortly
00521   usleep(0);
00522
00523   long int remaining_usec = (until - now).in_usec();
00524   while ( remaining_usec > 0 ) {
00525     usleep(remaining_usec);
00526     now.stamp();
00527     remaining_usec = (until - now).in_usec();
00528   }
00529 }
00530
00531 
00532 /** Wait (sleep) for this system time.
00533  * This waits for as much time as this instance provides. Unlike wait() this
00534  * method calculates the time in system time, althouh the main clock may run
00535  * slower for example in a simulation. Note that you have to make sure that you
00536  * call this on a sensible time range. You probably do not want to wait for
00537  * almost 40 years when passing a time point...
00538  */
00539 void
00540 Time::wait_systime()
00541 {
00542   Time until, now;
00543
00544   __clock->get_systime(until);
00545   until += *this;
00546
00547   __clock->get_systime(now);
00548
00549   // we want to release run status at least shortly
00550   usleep(0);
00551
00552   long int remaining_usec = (until - now).in_usec();
00553   while ( remaining_usec > 0 ) {
00554     usleep(remaining_usec);
00555     __clock->get_systime(now);
00556     remaining_usec = (until - now).in_usec();
00557   }
00558 }
00559 
00560 /** Output function.
00561  * @return a pointer to a member containing a string represenation of
00562  * the given time. If seconds is smaller than 1 billion it is assumed that
00563  * this time represents a time range rather than a point in time and
00564  * the time is formatted as seconds.microseconds, otherwise the time
00565  * is formatted either via localtime() (if utc is false) or gmtime (if utc
00566  * is true).
00567  * @param utc true to get type formatted in UTC, otherwise local time
00568  */
00569 const char *
00570 Time::str(bool utc)
00571 {
00572   // allocate time string if not done yet
00573   if ( ! __timestr )  __timestr = (char *)malloc(TIMESTR_SIZE);
00574
00575   // heuristic to distinguish times and time ranges
00576   if (__time.tv_sec < 1000000000) {
00577 #ifdef __FreeBSD__
00578     snprintf(__timestr, TIMESTR_SIZE, "%i:%li", __time.tv_sec, __time.tv_usec);
00579 #else
00580     snprintf(__timestr, TIMESTR_SIZE, "%li:%li", __time.tv_sec, __time.tv_usec);
00581 #endif
00582   } else {
00583     tm time_tm;
00584     if ( utc ) {
00585       gmtime_r( &(__time.tv_sec), &time_tm );
00586     } else {
00587       localtime_r( &(__time.tv_sec), &time_tm );
00588     }
00589     asctime_r(&time_tm, __timestr);
00590     __timestr[strlen(__timestr) - 1] = 0;
00591   }
00592
00593   return __timestr;
00594 }
00595
00596 
00597 /** Output function.
00598  * This is the thread-safe version of str().
00599  * @param s pointer to a string of at least TIMESTR_SIZE bytes.
00600  * @param utc true to get type formatted in UTC, otherwise local time
00601  */
00602 void
00603 Time::str_r(char *s, bool utc)
00604 {
00605   // heuristic to distinguish times and time ranges
00606   if (__time.tv_sec < 1000000000) {
00607 #ifdef __FreeBSD__
00608     snprintf(s, TIMESTR_SIZE, "%i:%li", __time.tv_sec, __time.tv_usec);
00609 #else
00610     snprintf(s, TIMESTR_SIZE, "%li:%li", __time.tv_sec, __time.tv_usec);
00611 #endif
00612   } else {
00613     tm time_tm;
00614     if ( utc ) {
00615       gmtime_r( &(__time.tv_sec), &time_tm );
00616     } else {
00617       localtime_r( &(__time.tv_sec), &time_tm );
00618     }
00619     asctime_r(&time_tm, s);
00620     s[strlen(s) - 1] = 0;
00621   }
00622 }
00623
00624 } // end namespace fawkes