General IRI utilities
ctime.cpp
1 // Copyright (C) 2009-2010 Institut de Robòtica i Informàtica Industrial, CSIC-UPC.
2 // Author Sergi Hernandez (shernand@iri.upc.edu)
3 // All rights reserved.
4 //
5 // This file is part of iriutils
6 // iriutils is free software: you can redistribute it and/or modify
7 // it under the terms of the GNU Lesser General Public License as published by
8 // the Free Software Foundation, either version 3 of the License, or
9 // at your option) any later version.
10 //
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public License
17 // along with this program. If not, see <http://www.gnu.org/licenses/>.
18 
19 #include "ctime.h"
20 using namespace std;
21 
22 // static members
23 CTime CTime::zero;
24 
25 //X
26 // CONSTRUCTOR / DESTRUCTOR
27 //
28 // CONSTRUCTOR
29 // set own_time to current time
31 {
32  this->use_zero = false;
33  this->set();
34  this->setFormat(ctf_us);
35 }
36 
37 CTime::CTime(double relative)
38 {
39  this->set(relative);
40 }
41 
42 // DESTRUCTOR
43 //
45 {
46 }
47 
48 //
49 // GET TIME
50 //
51 
52 unsigned long CTime::seconds(void)
53 {
54  return sec;
55 }
56 
57 unsigned long CTime::nanoseconds(void)
58 {
59  return nsec;
60 }
61 
62 // IN SECONDS (1.234)
63 
65 {
66  return (double)this->sec + (double)this->nsec/1000000000;
67 }
68 
69 // IN MILLISECONDS (1234)
71 {
72  return ( (double) ( this->sec * 1000 + this->nsec / 1000000 ));
73 }
74 
76 {
77  return ( (double) ( this->sec * 1000000 + this->nsec / 1000 ));
78 }
79 
80 // IN TIMESPEC
81 // timespec { 1, 234000000 }
83 {
84  timespec t;
85 
86  t.tv_sec = (long) this->sec;
87  t.tv_nsec = (long) this->nsec;
88 
89  return t;
90 }
91 
93 {
94  timeval t;
95 
96  t.tv_sec = (long) this->sec;
97  t.tv_usec = (long) (this->nsec/1000);
98 
99  return t;
100 }
101 
103 {
104  return (time_t)this->sec;
105 }
106 
107 
108 // SET TIME
109 // SET (Current time)
110 void CTime::set(double milliseconds)
111 {
112  timespec time_temp;
113  if(milliseconds<0.0)
114  {
115  #if defined __APPLE__
116  struct timeval tv;
117  gettimeofday(&tv, NULL);
118  time_temp.tv_sec = tv.tv_sec;
119  time_temp.tv_nsec = tv.tv_usec*1000;
120  #else
121  clock_gettime(CLOCK_REALTIME, &time_temp );
122  #endif
123  }
124  else
125  {
126  time_temp = this->msToTimespec(milliseconds);
127  }
128  this->sec = time_temp.tv_sec;
129  this->nsec = time_temp.tv_nsec;
130  if(this->use_zero && milliseconds<0.0)
131  {
132  CTime tmp;
133  tmp.sec = this->sec;
134  tmp.nsec = this->nsec;
135  tmp = diff(tmp,this->zero);
136  this->sec = tmp.sec;
137  this->nsec = tmp.nsec;
138  }
139 }
140 
142 {
143  this->zero.set();
144  this->use_zero = true;
145 }
146 
148  {
149  return this->zero;
150  }
151 
153 {
154  this->zero.set(0);
155  this->use_zero = false;
156 }
157 
158 void CTime::useRef(bool use)
159 {
160  if(*this >= this->zero)
161  {
162  *this = diff(*this,this->zero);
163  }
164  else{
165  *this = this->zero;
166  }
167  this->use_zero = use;
168 }
169 
171 {
172  return this->use_zero;
173 }
174 
175 CTime CTime::diff(CTime &t1, CTime &t0)
176 {
177  long long s,n;
178 
179  s = (long long)t1.sec - (long long)t0.sec;
180  n = (long long)t1.nsec - (long long)t0.nsec;
181 
182  if ( n < 0 )
183  {
184  s -= 1;
185  n += 1000000000;
186  }
187 
188  if (s < 0)
189  throw CTimeException(_HERE_,"negative time");
190 
191  CTime tmp;
192  tmp.sec=s;
193  tmp.nsec=n;
194 
195  return tmp;
196 }
197 
198 // OPERATIONS (t1-t0)
200 {
201  CTime t1;
202  t1.sec=this->sec;
203  t1.nsec=this->nsec;
204 
205  return diff(t1,t0);
206 }
207 
209 {
210  CTime tmp;
211  unsigned long tn;
212 
213  if ( this->sec + t.sec < ULONG_MAX )
214  {
215  tn = this->nsec + t.nsec;
216  tmp.sec = this->sec + t.sec;
217 
218  if( tn / 1000000000 > 0)
219  tmp.sec++;
220 
221  tmp.nsec = (this->nsec + t.nsec) % 1000000000;
222  }else{
223  throw CTimeException(_HERE_,"Result higher than ulong max");
224  }
225 
226  return tmp;
227 }
228 
230 {
231  CTime tmp;
232  double s,ns,t;
233 
234  t = (double) this->sec + (((double) this->nsec) / 1000000000) ;
235  t /= div;
236  ns = modf( t , &s);
237 
238  tmp.sec = (unsigned long) s;
239  tmp.nsec = (unsigned long)( ns * 1000000000 );
240 
241  return tmp;
242 }
243 
245 {
246  return( (this->sec == t.sec) && (this->nsec == t.nsec) );
247 }
248 
250 {
251  return( (this->sec != t.sec) || (this->nsec != t.nsec) );
252 }
253 
255 {
256  if(this->sec == t.sec)
257  return((this->nsec >= t.nsec));
258  else
259  return((this->sec > t.sec));
260 }
261 
263 {
264  if(this->sec == t.sec)
265  return((this->nsec <= t.nsec));
266  else
267  return((this->sec < t.sec));
268 }
269 
271 {
272  if(this->sec == t.sec)
273  return((this->nsec > t.nsec));
274  else
275  return((this->sec > t.sec));
276 }
277 
279 {
280  if(this->sec == t.sec)
281  return((this->nsec < t.nsec));
282  else
283  return((this->sec < t.sec));
284 }
285 
286 std::ostream& operator << (std::ostream &o,CTime &t)
287 {
288  o << t.getString();
289 
290  return o;
291 }
292 
293 std::string CTime::getString()
294 {
295  int ms=0,us=0;
296  char outstr [80];
297  struct tm * timeinfo;
298  std::string extra_zero;
299  std::stringstream output;
300 
301  switch(this->print_format)
302  {
303  default:
304  case ctf_secnano:
305  //sec nsec
306  //o << t.own_time.tv_sec << " " << t.own_time.tv_nsec;
307  if(this->nsec<10) extra_zero = "00000000";
308  else if(this->nsec<100) extra_zero = "0000000";
309  else if(this->nsec<1000) extra_zero = "000000";
310  else if(this->nsec<10000) extra_zero = "00000";
311  else if(this->nsec<100000) extra_zero = "0000";
312  else if(this->nsec<1000000) extra_zero = "000";
313  else if(this->nsec<10000000) extra_zero = "00";
314  else if(this->nsec<100000000) extra_zero = "0";
315  output << this->sec << " " << extra_zero << this->nsec;
316  break;
317  case ctf_datetime:
318  //YYYY-MM-DD,HH:MM:SS
319  timeinfo = localtime ( (time_t *)&this->sec );
320  strftime (outstr,23,"%F,%T",timeinfo);
321  output << outstr;
322  break;
323  case ctf_dtfile:
324  //YYYY-MM-DD-HHMMSS-MS
325  timeinfo = localtime ( (time_t *)&this->sec );
326  strftime (outstr,23,"%F-%H%M%S-",timeinfo);
327  output << outstr << (this->nsec/1000000);
328  break;
329  case ctf_ms:
330  // sec.0ms
331  ms = round( this->nsec/1000000 );
332  if(ms<100 && ms>0) extra_zero = "0";
333  if(ms<10 && ms>0) extra_zero = "00";
334  output << this->sec << "." << extra_zero << ms ;
335  break;
336  case ctf_us:
337  // sec.0000us
338  us = round( this->nsec/1000 );
339  if(us<10) extra_zero = "00000";
340  else if(us<100) extra_zero = "0000";
341  else if(us<1000) extra_zero = "000";
342  else if(us<10000) extra_zero = "00";
343  else if(us<100000) extra_zero = "0";
344  output << this->sec << "." << extra_zero << us ;
345  break;
346  }
347 
348  return output.str();
349 }
350 
351 void CTime::setFormat(ctimeformat format)
352 {
353  this->print_format = format;
354 }
355 
356 ctimeformat CTime::getFormat()
357 {
358  return this->print_format;
359 }
360 
361 
362 // CONVERSION
363 // timespec to milliseconds
364 double CTime::timespecToMs( timespec time )
365 {
366  return( time.tv_sec*1000.0 + (time.tv_nsec/1000000.0) );
367 }
368 
369 // milliseconds to timespec
370 timespec CTime::msToTimespec( double time_ms )
371 {
372  timespec temp;
373 
374  double seconds = (double)time_ms/1000.0;
375  temp.tv_sec = (long long)floor(seconds);
376  temp.tv_nsec = (long long)floor((seconds-temp.tv_sec)*1000000000);
377 
378  return temp;
379 }
380 
381 
double getTimeInMilliseconds(void)
Get time in milliseconds.
Definition: ctime.cpp:70
unsigned long nanoseconds(void)
Get Nanoseconds.
Definition: ctime.cpp:57
CTime exception class.
bool operator<=(CTime &t)
Comparison <= operator.
Definition: ctime.cpp:262
~CTime()
Destructor.
Definition: ctime.cpp:44
CTime operator+(CTime &t)
Calculates time addition.
Definition: ctime.cpp:208
static double timespecToMs(timespec t)
conversion from timespec to milliseconds
Definition: ctime.cpp:364
long getTimeInMicroseconds(void)
Get time in microseconds.
Definition: ctime.cpp:75
void useRef(bool use)
sets if use or not the reference internal time
Definition: ctime.cpp:158
bool operator!=(CTime &t)
Comparison operator.
Definition: ctime.cpp:249
void setRef()
Sets the internal reference time.
Definition: ctime.cpp:141
CTime operator-(CTime &t)
Calculates time difference.
Definition: ctime.cpp:199
timeval getTimeInTimeval(void)
Get time in a timeval strcuture.
Definition: ctime.cpp:92
unsigned long seconds(void)
Get Seconds.
Definition: ctime.cpp:52
bool operator>(CTime &t)
Comparison > operator.
Definition: ctime.cpp:270
bool operator==(CTime &t)
Comparison operator.
Definition: ctime.cpp:244
CTime()
Constructor.
Definition: ctime.cpp:30
std::string getString(void)
Gives a formatted string of this time.
Definition: ctime.cpp:293
time_t getTimeInTime_t(void)
Get time in time_t.
Definition: ctime.cpp:102
Implementation of a time class and operations.
Definition: ctime.h:75
ctimeformat getFormat()
Gets output string format.
Definition: ctime.cpp:356
static timespec msToTimespec(double ms)
conversion from milliseconds to timespec
Definition: ctime.cpp:370
timespec getTimeInTimespec(void)
Get time in a timespec strcuture.
Definition: ctime.cpp:82
double getTimeInSeconds(void)
Get time in seconds.
Definition: ctime.cpp:64
void setFormat(ctimeformat format)
Sets output string format.
Definition: ctime.cpp:351
void set(double milliseconds=-1.0)
Sets the internal time.
Definition: ctime.cpp:110
bool operator<(CTime &t)
Comparison < operator.
Definition: ctime.cpp:278
bool isRefUsed()
Get if is used or not the reference internal time.
Definition: ctime.cpp:170
CTime operator/(int div)
Calculates division by integer.
Definition: ctime.cpp:229
bool operator>=(CTime &t)
Comparison >= operator.
Definition: ctime.cpp:254
CTime getRef()
Get the reference internal time.
Definition: ctime.cpp:147
void resetRef()
Resets the reference time to the epoch.
Definition: ctime.cpp:152