xstime.c
Go to the documentation of this file.
1 
2 // Copyright (c) 2003-2021 Xsens Technologies B.V. or subsidiaries worldwide.
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without modification,
6 // are permitted provided that the following conditions are met:
7 //
8 // 1. Redistributions of source code must retain the above copyright notice,
9 // this list of conditions, and the following disclaimer.
10 //
11 // 2. Redistributions in binary form must reproduce the above copyright notice,
12 // this list of conditions, and the following disclaimer in the documentation
13 // and/or other materials provided with the distribution.
14 //
15 // 3. Neither the names of the copyright holders nor the names of their contributors
16 // may be used to endorse or promote products derived from this software without
17 // specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
20 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
22 // THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
24 // OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY OR
26 // TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.THE LAWS OF THE NETHERLANDS
28 // SHALL BE EXCLUSIVELY APPLICABLE AND ANY DISPUTES SHALL BE FINALLY SETTLED UNDER THE RULES
29 // OF ARBITRATION OF THE INTERNATIONAL CHAMBER OF COMMERCE IN THE HAGUE BY ONE OR MORE
30 // ARBITRATORS APPOINTED IN ACCORDANCE WITH SAID RULES.
31 //
32 
33 
34 // Copyright (c) 2003-2021 Xsens Technologies B.V. or subsidiaries worldwide.
35 // All rights reserved.
36 //
37 // Redistribution and use in source and binary forms, with or without modification,
38 // are permitted provided that the following conditions are met:
39 //
40 // 1. Redistributions of source code must retain the above copyright notice,
41 // this list of conditions, and the following disclaimer.
42 //
43 // 2. Redistributions in binary form must reproduce the above copyright notice,
44 // this list of conditions, and the following disclaimer in the documentation
45 // and/or other materials provided with the distribution.
46 //
47 // 3. Neither the names of the copyright holders nor the names of their contributors
48 // may be used to endorse or promote products derived from this software without
49 // specific prior written permission.
50 //
51 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
52 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
53 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
54 // THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 // SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
56 // OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
57 // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY OR
58 // TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
59 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.THE LAWS OF THE NETHERLANDS
60 // SHALL BE EXCLUSIVELY APPLICABLE AND ANY DISPUTES SHALL BE FINALLY SETTLED UNDER THE RULES
61 // OF ARBITRATION OF THE INTERNATIONAL CHAMBER OF COMMERCE IN THE HAGUE BY ONE OR MORE
62 // ARBITRATORS APPOINTED IN ACCORDANCE WITH SAID RULES.
63 //
64 
65 // Note, this function requires compiler option "-lrt" to be set when compiling with gcc
66 #include "xstime.h"
67 #include "xstimestamp.h"
68 #include <stdio.h>
69 #include <wchar.h>
70 
71 #ifdef _WIN32
72  #include <windows.h>
73  #include "xssimpleversion.h"
74 #else
75  #include <errno.h>
76  #include <unistd.h>
77  #include <sys/time.h>
78  #include <pthread.h>
79  #include <string.h>
80 #endif
81 #include <time.h>
82 
87 const XsTimeStamp XsTime_secPerDay = { 60 * 60 * 24LL };
89 
91 const XsTimeStamp XsTime_milliSecPerDay = { 60 * 60 * 24 * 1000LL };
92 
94 const XsTimeStamp XsTime_timeStampMax = { 0x7FFFFFFFFFFFFFFFLL };
95 
99 #if 0 // def __APPLE__, it is in fact available on apple, so...
100 
105 #ifndef CLOCK_REALTIME
106  #define CLOCK_REALTIME 0
107 #endif
108 static int clock_gettime(int clk_id, struct timespec* tp)
109 {
110  (void)clk_id;
111  struct timeval now;
112 
113  int rv = gettimeofday(&now, NULL);
114  if (rv != 0)
115  return rv;
116 
117  tp->tv_sec = now.tv_sec;
118  tp->tv_nsec = now.tv_usec * 1000;
119 
120  return 0;
121 }
122 #endif
123 
128 
134 uint32_t XsTime_getTimeOfDay(struct tm* date_, time_t* secs_)
135 {
136 #ifdef _WIN32
137  typedef void(WINAPI * GetSystemTimeType)(LPFILETIME);
138  static GetSystemTimeType getSystemTime = 0;
139  static int havePreciseFileTime = 0;
140  if (getSystemTime == 0)
141  {
142  XsSimpleVersion ver;
144  if (ver.m_major >= 8)
145  {
146  getSystemTime = (GetSystemTimeType)GetProcAddress(GetModuleHandleA("Kernel32"), "GetSystemTimePreciseAsFileTime");
147  if (getSystemTime)
148  havePreciseFileTime = 1;
149  else
150  getSystemTime = GetSystemTimeAsFileTime;
151  }
152  else
153  getSystemTime = GetSystemTimeAsFileTime;
154  }
155 
156  if (havePreciseFileTime)
157  {
158  int64_t t;
159  FILETIME now;
160  __time64_t tin;
161  getSystemTime(&now);
162  t = (int64_t)(((((uint64_t) now.dwHighDateTime << 32) | now.dwLowDateTime) / 10000) - 11644473600000);
163  tin = t / 1000;
164  if (date_ != NULL)
165  _localtime64_s(date_, &tin);
166  if (secs_ != NULL)
167  *secs_ = (time_t) tin;
168  return (uint32_t)(t % (XsTime_secPerDay.m_msTime * 1000));
169  }
170  else
171  {
172  // CORRECTION_DELTA_MS is the maximum allowed difference between the system time and the performance counter time. This depends on the granularity of the clocks.
173  static const int64_t CORRECTION_DELTA_MS = 32;
174  static int64_t startTimePerfCount;
175  static int64_t startTimeSysTime;
176  static int64_t perfCountFreq = 0;
177  int64_t t;
178  LARGE_INTEGER pc;
179  FILETIME now;
180  __time64_t tin;
181 
182  GetSystemTimeAsFileTime(&now);
183  t = (int64_t)(((((uint64_t) now.dwHighDateTime << 32) | now.dwLowDateTime) / 10000) - 11644473600000);
184 
185  if (QueryPerformanceCounter(&pc))
186  {
187  int64_t tNow;
188  if (!perfCountFreq)
189  {
190  LARGE_INTEGER tmp;
191  QueryPerformanceFrequency(&tmp);
192  perfCountFreq = tmp.QuadPart;
193  startTimePerfCount = pc.QuadPart;
194  startTimeSysTime = t;
195  }
196 
197  tNow = startTimeSysTime + (1000 * (pc.QuadPart - startTimePerfCount)) / perfCountFreq; //lint !e414
198 
199  if (t > tNow || (tNow - t) > CORRECTION_DELTA_MS)
200  {
201  startTimePerfCount = pc.QuadPart;
202  startTimeSysTime = t;
203  }
204  else
205  t = tNow;
206  }
207 
208  tin = t / 1000;
209  if (date_ != NULL)
210  _localtime64_s(date_, &tin);
211  if (secs_ != NULL)
212  *secs_ = (time_t) tin;
213  return (uint32_t)(t % (XsTime_secPerDay.m_msTime * 1000));
214  }
215 #else
216  struct timespec tp;
217  clock_gettime(CLOCK_REALTIME, &tp); // compile with -lrt
218 
219  if (date_ != NULL)
220  localtime_r(&tp.tv_sec, date_);
221 
222  if (secs_ != NULL)
223  secs_[0] = tp.tv_sec;
224 
225  // 86400 = 24*60*60 = secs in a day, this gives us the seconds since midnight
226  return (uint32_t)((1000 * (tp.tv_sec % XsTime_secPerDay.m_msTime)) + (tp.tv_nsec / 1000000));
227 #endif
228 }
229 
234 int64_t XsTime_getDateTime(struct tm* date)
235 {
236 #ifdef _WIN32
237  __time64_t t;
238  _time64(&t);
239  if (date != 0)
240  _localtime64_s(date, &t);
241  return (int64_t)t;
242 #else
243  time_t t;
244  time(&t);
245  if (date != 0)
246  {
247  struct tm* result = localtime(&t);
248  memcpy(date, result, sizeof(struct tm));
249  }
250  return (int64_t)t;
251 #endif
252 }
253 
260 void XsTime_getDateAsString(char* dest, const struct tm* date)
261 {
262  struct tm dt;
263  unsigned int year, month;
264 
265  if (date != 0)
266  dt = *date;
267  else
268  XsTime_getDateTime(&dt);
269 
270  year = (unsigned int) (dt.tm_year + 1900);
271  month = (unsigned int) (dt.tm_mon + 1);
272 
273  char tmpDest[9];
274 #if defined(__GNUC__) && !defined(__APPLE__) && !defined(__ANDROID_API__)
275  #pragma GCC diagnostic push
276  #pragma GCC diagnostic ignored "-Wformat-truncation" // valid date values will always fit properly
277 #endif
278  snprintf(tmpDest, 9, "%04u%02u%02u", year, month, (unsigned int) dt.tm_mday);
279 #if defined(__GNUC__) && !defined(__APPLE__) && !defined(__ANDROID_API__)
280  #pragma GCC diagnostic pop
281 #endif
282  memcpy(dest, tmpDest, 8);
283 }
284 
292 void XsTime_getTimeAsString(char* dest, const struct tm* date)
293 {
294  struct tm dt;
295 
296  if (date != 0)
297  dt = *date;
298  else
299  XsTime_getDateTime(&dt);
300 
301  char tmpDest[9];
302  snprintf(tmpDest, 9, "%02d%02d%02d%02d", dt.tm_hour, dt.tm_min, dt.tm_sec, 0);
303  memcpy(dest, tmpDest, 8);
304 }
305 
312 void XsTime_getDateAsWString(wchar_t* dest, const struct tm* date)
313 {
314  struct tm dt;
315  int year, month;
316 
317  if (date != 0)
318  dt = *date;
319  else
320  XsTime_getDateTime(&dt);
321 
322  year = dt.tm_year + 1900;
323  month = dt.tm_mon + 1;
324  swprintf(dest, 9, L"%04d%02d%02d", year, month, dt.tm_mday);
325 }
326 
334 void XsTime_getTimeAsWString(wchar_t* dest, const struct tm* date)
335 {
336  struct tm dt;
337 
338  if (date != 0)
339  dt = *date;
340  else
341  XsTime_getDateTime(&dt);
342 
343  swprintf(dest, 9, L"%02d%02d%02d%02d", dt.tm_hour, dt.tm_min, dt.tm_sec, 0);
344 }
345 
354 {
355 #ifdef _WIN32
356  Sleep(ms);
357 #else
358  XsTime_udelay(ms * 1000);
359 #endif
360 }
361 
369 void XsTime_udelay(uint64_t us)
370 {
371 #ifdef _WIN32
372  LARGE_INTEGER freq, start, stop;
373  double countPerMicroSecond ;
374  QueryPerformanceCounter(&start);
375  QueryPerformanceFrequency(&freq);
376  countPerMicroSecond = freq.QuadPart / 1.0e6;
377  do
378  {
379  QueryPerformanceCounter(&stop);
380  } while (start.QuadPart + ((double)(us) * countPerMicroSecond) > stop.QuadPart);
381 #else
382  struct timespec ts;
383  int ret = -1;
384 
385  ts.tv_sec = us / 1000000;
386  ts.tv_nsec = ((long)us - (ts.tv_sec * 1000000)) * 1000;
387 
388  while (ret)
389  {
390  ret = nanosleep(&ts, &ts);
391  if (ret)
392  assert(errno == EINTR);
393  }
394 #endif
395 }
396 
402 {
403  XsTimeStamp tmp;
404  time_t s;
405 
406  if (now == 0)
407  now = &tmp;
408 
409  now->m_msTime = (long long) XsTime_getTimeOfDay(NULL, &s);
410  now->m_msTime = (now->m_msTime % 1000) + (((long long)s) * 1000);
411 
412  return now->m_msTime;
413 }
414 
416 int64_t XsTime_utcToLocalValue = 0;
417 int64_t XsTime_localToUtcValue = 0;
418 
425 {
426  int64_t tutc, tloc;
427 #ifdef _WIN32
428  FILETIME now, nowloc;
429 
430  GetSystemTimeAsFileTime(&now);
431  FileTimeToLocalFileTime(&now, &nowloc);
432 
433  tutc = (int64_t)(((((uint64_t) now.dwHighDateTime << 32) | now.dwLowDateTime) / 10000) - 11644473600000);
434  tloc = (int64_t)(((((uint64_t) nowloc.dwHighDateTime << 32) | nowloc.dwLowDateTime) / 10000) - 11644473600000);
435 
436 #else
437  struct timespec tp;
438  struct tm now, nowloc;
439 
440  clock_gettime(CLOCK_REALTIME, &tp); // compile with -lrt
441  gmtime_r(&tp.tv_sec, &now);
442  localtime_r(&tp.tv_sec, &nowloc);
443 
444  tutc = (int64_t) now.tm_min * 60000;
445  tloc = (int64_t) nowloc.tm_min * 60000;
446 #endif
447 
448  XsTime_utcToLocalValue = tloc - tutc;
449  XsTime_localToUtcValue = tutc - tloc;
450 
451  long long start = XsTime_timeStampNow(0);
452  while (XsTime_timeStampNow(0) - start < 32) {}
453 }
454 
460 {
461  return XsTime_utcToLocalValue;
462 }
463 
469 {
470  return XsTime_localToUtcValue;
471 }
472 
XsTime_initializeTime
void XsTime_initializeTime()
Stabilize the clock.
Definition: xstime.c:424
XsTime_secPerDay
const XsTimeStamp XsTime_secPerDay
The number of seconds in a normal day.
Definition: xstime.c:88
XsTime_udelay
void XsTime_udelay(uint64_t us)
Delays the current thread for at least us microseconds.
Definition: xstime.c:369
XsTime_msleep
void XsTime_msleep(uint32_t ms)
Make the current thread sleep for at least ms milliseconds.
Definition: xstime.c:353
s
XmlRpcServer s
XsTime_timeStampMax
const XsTimeStamp XsTime_timeStampMax
The maximum positive value of an XsTimeStamp value.
Definition: xstime.c:94
time.h
XsSimpleVersion_osVersion
void XsSimpleVersion_osVersion(XsSimpleVersion *thisPtr)
Platdorm independent request of the OS version. Results are cached and of course platform dependent.
Definition: xssimpleversion.c:120
xstimestamp.h
XsSimpleVersion::m_major
uint8_t m_major
The major part of the version number.
Definition: xssimpleversion.h:219
xssimpleversion.h
XsSimpleVersion
A class to store version information.
Definition: xssimpleversion.h:91
XsTime_getTimeOfDay
uint32_t XsTime_getTimeOfDay(struct tm *date_, time_t *secs_)
The function returns the current time of day in ms since midnight.
Definition: xstime.c:134
XsTime_getDateTime
int64_t XsTime_getDateTime(struct tm *date)
Retrieves the date and time (platform-independent)
Definition: xstime.c:234
XsTime_milliSecPerDay
const XsTimeStamp XsTime_milliSecPerDay
The number of milliseconds in a normal day.
Definition: xstime.c:91
XsTime_localToUtc
int64_t XsTime_localToUtc()
Returns the conversion value from local time to UTC time in ms.
Definition: xstime.c:468
uint32_t
unsigned int uint32_t
Definition: pstdint.h:485
XsTime_getTimeAsWString
void XsTime_getTimeAsWString(wchar_t *dest, const struct tm *date)
Retrieves the time as binary The format is HHMMSShh (where H is hour and 'h' is hundredths) so 14:25:...
Definition: xstime.c:334
XsTime_getTimeAsString
void XsTime_getTimeAsString(char *dest, const struct tm *date)
Retrieves the time as binary The format is HHMMSShh (where H is hour and 'h' is hundredths) so 14:25:...
Definition: xstime.c:292
XsTime_getDateAsWString
void XsTime_getDateAsWString(wchar_t *dest, const struct tm *date)
Retrieves the date as wstring representation The format is YYYYMMDD so 25 dec 2010 is stored as an ar...
Definition: xstime.c:312
XsTime_getDateAsString
void XsTime_getDateAsString(char *dest, const struct tm *date)
Retrieves the date as string representation The format is YYYYMMDD so 25 dec 2010 is stored as an arr...
Definition: xstime.c:260
start
ROSCPP_DECL void start()
XsTime_timeStampNow
int64_t XsTime_timeStampNow(XsTimeStamp *now)
Returns the current time in ms since the epoch (Jan 1st 1970)
Definition: xstime.c:401
XsTimeStamp::m_msTime
int64_t m_msTime
The timestamp value.
Definition: xstimestamp.h:455
XsTime_utcToLocal
int64_t XsTime_utcToLocal()
Returns the conversion value from UTC time to local time in ms.
Definition: xstime.c:459
xstime.h
XsTimeStamp
This class contains method to set, retrieve and compare timestamps.
Definition: xstimestamp.h:115


xsens_mti_driver
Author(s):
autogenerated on Sun Sep 3 2023 02:43:20