appkit  1.5.1
RoadNarrows Robotics Application Kit
Time.cxx
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////////////
2 //
3 // Package: RoadNarrows Robotics Application Tool Kit
4 //
5 // Library: librnr_appkit
6 //
7 // File: Time.cxx
8 //
9 //
10 /*! \file
11  *
12  * $LastChangedDate: 2015-11-09 17:38:34 -0700 (Mon, 09 Nov 2015) $
13  * $Rev: 4195 $
14  *
15  * \brief Time functions and class implementations.
16  *
17  * \author Robin Knight (robin.knight@roadnarrows.com)
18  *
19  * \par Copyright
20  * \h_copy 2015-2017. RoadNarrows LLC.\n
21  * http://www.roadnarrows.com\n
22  * All Rights Reserved
23  */
24 /*
25  * @EulaBegin@
26  * @EulaEnd@
27  */
28 ////////////////////////////////////////////////////////////////////////////////
29 
30 
31 #include <sys/types.h>
32 #include <sys/time.h>
33 #include <time.h>
34 #include <unistd.h>
35 #include <math.h>
36 #include <stdio.h>
37 #include <errno.h>
38 
39 #include <iostream>
40 #include <iomanip>
41 #include <sstream>
42 
43 #include "rnr/rnrconfig.h"
44 #include "rnr/log.h"
45 
47 #include "rnr/appkit/Time.h"
48 
49 using namespace std;
50 using namespace rnr;
51 using namespace rnr::chronos;
52 
53 
54 ostream &operator<<(ostream &os, const timespec &obj)
55 {
56  char c = os.fill();
57  size_t w = os.width();
58 
59  os << obj.tv_sec << "."
60  << setw(9) << setfill('0') << obj.tv_nsec
61  << setfill(c) << setw(w);
62 
63  return os;
64 }
65 
66 namespace rnr
67 {
68  namespace chronos
69  {
70  timespec now()
71  {
72  timespec ts;
73 
74  if( now(ts) != OK )
75  {
76  clear(ts);
77  }
78  return ts;
79  }
80 
81  int now(timespec &ts)
82  {
83  return clock_gettime(CLOCK_REALTIME, &ts) == 0? OK: RC_ERROR;
84  }
85 
86  double toFp(const timespec &ts)
87  {
88  return (double)ts.tv_sec + (double)ts.tv_nsec/ (double)BILLION;
89  }
90 
91  timespec toTs(const double &t)
92  {
93  timespec ts;
94  double sec, nsec;
95 
96  sec = floor(t);
97  nsec = (t - sec) * (double)BILLION;
98 
99  ts.tv_sec = (long)sec;
100  ts.tv_nsec = (long)nsec;
101 
102  return ts;
103  }
104 
105  bool isSet(const timespec &ts)
106  {
107  return (ts.tv_sec != 0) || (ts.tv_nsec != 0);
108  }
109 
110  void clear(timespec &ts)
111  {
112  ts.tv_sec = 0;
113  ts.tv_nsec = 0;
114  }
115 
116  timespec add(const timespec &a, const timespec &b)
117  {
118  timespec ts;
119 
120  ts.tv_sec = a.tv_sec + b.tv_sec;
121  ts.tv_nsec = a.tv_nsec + b.tv_nsec;
122 
123  return rnr::chronos::normalize(ts);
124  }
125 
126  timespec sub(const timespec &a, const timespec &b)
127  {
128  timespec ts;
129 
130  ts.tv_sec = a.tv_sec - b.tv_sec;
131  ts.tv_nsec = a.tv_nsec - b.tv_nsec;
132 
133  return rnr::chronos::normalize(ts);
134  }
135 
136  timespec normalize(const timespec &a)
137  {
138  timespec ts = a;
139 
140  while( ts.tv_nsec >= BILLION )
141  {
142  ts.tv_sec += 1;
143  ts.tv_nsec -= BILLION;
144  }
145 
146  while( ts.tv_nsec < 0 )
147  {
148  ts.tv_sec -= 1;
149  ts.tv_nsec += BILLION;
150  }
151 
152  return ts;
153  }
154  } // namespace chronos
155 } // namesapce rnr
156 
157 
158 //------------------------------------------------------------------------------
159 // Time Class
160 //------------------------------------------------------------------------------
161 
162 Time::Time()
163 {
164  clear();
165 }
166 
167 Time::Time(const timespec &ts)
168 {
169  m_tsTime = ts;
170  m_fpTime = chronos::toFp(m_tsTime);
171 }
172 
173 Time::Time(const double &t)
174 {
175  m_fpTime = t;
176  m_tsTime = chronos::toTs(m_fpTime);
177 }
178 
179 Time::Time(const Time &src)
180 {
181  m_tsTime = src.m_tsTime;
182  m_fpTime = src.m_fpTime;
183 }
184 
186 {
187  chronos::clear(m_tsTime);
188  m_fpTime = 0.0;
189 }
190 
191 
192 // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
193 // Clock and Time Functions
194 // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
195 
196 double Time::getResolution()
197 {
198  timespec res;
199 
200  if( clock_getres(CLOCK_REALTIME, &res) < 0 )
201  {
202  chronos::clear(res);
203  }
204 
205  return chronos::toFp(res);
206 }
207 
208 double Time::now()
209 {
210  timespec ts = chronos::now();
211 
212  return chronos::toFp(ts);
213 }
214 
215 double Time::markNow()
216 {
217  chronos::now(m_tsTime);
218  m_fpTime = chronos::toFp(m_tsTime);
219  return m_fpTime;
220 }
221 
222 
223 // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
224 // (Compound) Assignment Operators
225 // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
226 
227 Time &Time::operator=(const Time &b)
228 {
229  m_tsTime = b.m_tsTime;
230  m_fpTime = b.m_fpTime;
231  return *this;
232 }
233 
234 Time &Time::operator=(const timespec &b)
235 {
236  m_tsTime = b;
237  m_fpTime = chronos::toFp(m_tsTime);
238  return *this;
239 }
240 
241 Time &Time::operator=(const double &b)
242 {
243  m_fpTime = b;
244  m_tsTime = chronos::toTs(m_fpTime);
245  return *this;
246 }
247 
248 Time &Time::operator+=(const Time &b)
249 {
250  m_tsTime = chronos::add(m_tsTime, b.m_tsTime);
251  m_fpTime = chronos::toFp(m_tsTime);
252  return *this;
253 }
254 
255 Time &Time::operator+=(const timespec &b)
256 {
257  m_tsTime = chronos::add(m_tsTime, b);
258  m_fpTime = chronos::toFp(m_tsTime);
259  return *this;
260 }
261 
262 Time &Time::operator+=(const double &b)
263 {
264  m_fpTime += b;
265  m_tsTime = toTs(m_fpTime);
266  return *this;
267 }
268 
269 Time &Time::operator-=(const Time &b)
270 {
271  m_tsTime = chronos::sub(m_tsTime, b.m_tsTime);
272  m_fpTime = chronos::toFp(m_tsTime);
273  return *this;
274 }
275 
276 Time &Time::operator-=(const timespec &b)
277 {
278  m_tsTime = chronos::sub(m_tsTime, b);
279  m_fpTime = chronos::toFp(m_tsTime);
280  return *this;
281 }
282 
283 Time &Time::operator-=(const double &b)
284 {
285  m_fpTime -= b;
286  m_tsTime = chronos::toTs(m_fpTime);
287  return *this;
288 }
289 
290 Time &Time::operator*=(const double &b)
291 {
292  m_fpTime *= b;
293  m_tsTime = chronos::toTs(m_fpTime);
294  return *this;
295 }
296 
297 
298 // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
299 // Arithmetic Operators
300 // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
301 
302 
303 // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
304 // Comparison Operators
305 // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
306 
307 bool Time::operator<(const timespec &b)
308 {
309  if( m_tsTime.tv_sec < b.tv_sec )
310  {
311  return true;
312  }
313  else if( (m_tsTime.tv_sec == b.tv_sec) && (m_tsTime.tv_nsec < b.tv_nsec) )
314  {
315  return true;
316  }
317  else
318  {
319  return false;
320  }
321 }
322 
323 bool Time::operator>(const timespec &b)
324 {
325  if( m_tsTime.tv_sec > b.tv_sec )
326  {
327  return true;
328  }
329  else if( (m_tsTime.tv_sec == b.tv_sec) && (m_tsTime.tv_nsec > b.tv_nsec) )
330  {
331  return true;
332  }
333  else
334  {
335  return false;
336  }
337 }
338 
339 std::string Time::calendarTime(const int resSec) const
340 {
341  char buf[32]; // must be >= 26 bytes
342 
343  // "Wed Jun 30 21:49:08 2017\n"
344  if( ctime_r(&(m_tsTime.tv_sec), buf) == NULL )
345  {
346  return "??? ??? ?? ??:??:?? ????";
347  }
348 
349  string str(buf);
350 
351  str::rtrim(str);
352 
353  if( resSec > 0 )
354  {
355  stringstream ss;
356 
357  //
358  // if t = 153.096 seconds
359  // res = 2 res = 3
360  // t - floor(t) ==> 0.096 t - floor(t) ==> 0.096
361  // 0.096 * 10^2 ==> 9.6 0.096 * 10^3 ==> 96.0
362  // trunc(9.6) ==> 9.0 trunc(96.0) ==> 96.0
363  // out ==> 09 out ==> 096
364  //
365  int w = resSec <= 9? resSec: 9;
366  double y = (double)w;
367  long nsec = (long)trunc(((m_fpTime - floor(m_fpTime)) * pow(10.0, y)));
368 
369  ss << str.substr(0, 19);
370  ss << "." << std::setfill('0') << std::setw(w) << nsec;
371  ss << str.substr(20);
372 
373  return ss.str();
374  }
375  else
376  {
377  return str;
378  }
379 }
380 
381 ostream &rnr::chronos::operator<<(ostream &os, const Time &obj)
382 {
383  os << obj.m_tsTime;
384  return os;
385 }
386 
bool isSet(const timespec &a)
Check if timespec is set.
Definition: Time.cxx:105
timespec m_tsTime
time in timespec format
Definition: Time.h:617
double m_fpTime
time in floating point format
Definition: Time.h:618
std::string & rtrim(std::string &str)
Trim string in-place of trailing whitespace.
Definition: StringTheory.h:170
Time functions and class interfaces.
Chronos - God of Time.
Definition: Time.h:63
Time class.
Definition: Time.h:192
Of string spaces and their strangian operators.
std::ostream & operator<<(std::ostream &os, const Time &obj)
Time insertion operator.
double toFp(const timespec &ts)
Convert timespec to floating point number equivalent.
Definition: Time.cxx:86
void clear(timespec &ts)
Clear this object&#39;s time.
Definition: Time.cxx:110
timespec sub(const timespec &a, const timespec &b)
Subtract two timespecs.
Definition: Time.cxx:126
timespec toTs(const double &t)
Convert floating point seconds to timespec equivalent.
Definition: Time.cxx:91
timespec add(const timespec &a, const timespec &b)
Add two timespecs.
Definition: Time.cxx:116
timespec now()
Get the current time, indentified by CLOCK_REALTIME, since the last Epoch.
Definition: Time.cxx:70
RoadNarrows Robotics.
Definition: Camera.h:74
timespec normalize(const timespec &a)
Normalize the timespec.
Definition: Time.cxx:136
const long long BILLION
1,000,000,000
Definition: Time.h:66
std::ostream & operator<<(std::ostream &os, const timespec &obj)
A timespec insertion operator.