MRPT  1.9.9
datetime.cpp
Go to the documentation of this file.
1 /* +------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | https://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2020, Individual contributors, see AUTHORS file |
6  | See: https://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See: https://www.mrpt.org/License |
8  +------------------------------------------------------------------------+ */
9 
10 #include "system-precomp.h" // Precompiled headers
11 
12 #include <mrpt/core/exceptions.h>
13 #include <mrpt/system/datetime.h>
14 #include <mrpt/system/os.h>
15 
16 #ifdef _WIN32
17 #include <windows.h>
18 
19 #include <conio.h>
20 #include <direct.h>
21 #include <io.h>
22 #include <process.h>
23 #include <sys/utime.h>
24 #include <tlhelp32.h>
25 #else
26 #include <pthread.h>
27 #include <sys/select.h>
28 #include <sys/time.h>
29 #include <termios.h>
30 #include <unistd.h>
31 #include <utime.h>
32 #include <cerrno>
33 #endif
34 
35 #include <sys/stat.h>
36 #include <sys/types.h>
37 #include <cmath> // floor()
38 #include <ctime>
39 #include <iostream> // for the << operator
40 
41 using namespace mrpt;
42 using namespace mrpt::system;
43 using namespace std;
44 
46 {
47  return time_tToTimestamp(static_cast<double>(t));
48 }
49 
51 {
52  const double T = mrpt::system::timestampTotime_t(t);
53  double sec_frac = T - floor(T);
54  ASSERT_(sec_frac < 1.0);
55 
56  const auto tt = time_t(T);
57 
58  struct tm* parts = localTime ? localtime(&tt) : gmtime(&tt);
59  ASSERTMSG_(parts, "Malformed timestamp");
60 
61  p.year = parts->tm_year + 1900;
62  p.month = parts->tm_mon + 1;
63  p.day = parts->tm_mday;
64  p.day_of_week = parts->tm_wday + 1;
65  p.daylight_saving = parts->tm_isdst;
66  p.hour = parts->tm_hour;
67  p.minute = parts->tm_min;
68  p.second = parts->tm_sec + sec_frac;
69 }
70 
71 /*---------------------------------------------------------------
72  buildTimestampFromParts
73  ---------------------------------------------------------------*/
75 {
76  struct tm parts
77  {
78  };
79 
80  parts.tm_year = p.year - 1900;
81  parts.tm_mon = p.month - 1;
82  parts.tm_mday = p.day;
83  parts.tm_wday = p.day_of_week - 1;
84  parts.tm_isdst = p.daylight_saving;
85  parts.tm_hour = p.hour;
86  parts.tm_min = p.minute;
87  parts.tm_sec = int(p.second);
88 
89  double sec_frac = p.second - parts.tm_sec;
90 
91  time_t tt = mrpt::system::os::timegm(&parts); // Local time: mktime
92 
93  return mrpt::system::time_tToTimestamp(double(tt) + sec_frac);
94 }
95 
96 /*---------------------------------------------------------------
97  buildTimestampFromPartsLocalTime
98  ---------------------------------------------------------------*/
100 {
101  struct tm parts
102  {
103  };
104 
105  parts.tm_year = p.year - 1900;
106  parts.tm_mon = p.month - 1;
107  parts.tm_mday = p.day;
108  parts.tm_wday = p.day_of_week - 1;
109  parts.tm_isdst = p.daylight_saving;
110  parts.tm_hour = p.hour;
111  parts.tm_min = p.minute;
112  parts.tm_sec = int(p.second);
113 
114  double sec_frac = p.second - parts.tm_sec;
115 
116  time_t tt = mktime(&parts);
117 
118  return mrpt::system::time_tToTimestamp(double(tt) + sec_frac);
119 }
120 
121 /*---------------------------------------------------------------
122  formatTimeInterval
123  ---------------------------------------------------------------*/
124 string mrpt::system::formatTimeInterval(const double t)
125 {
126  double timeSeconds = (t < 0) ? (-t) : t;
127  std::string s;
128 
129  const auto nDays = static_cast<unsigned int>(timeSeconds / (3600 * 24));
130  timeSeconds -= nDays * 3600 * 24;
131  const auto nHours = static_cast<unsigned int>(timeSeconds / 3600);
132  timeSeconds -= nHours * 3600;
133  const auto nMins = static_cast<unsigned int>(timeSeconds / 60);
134  const auto nSecs = static_cast<unsigned int>(timeSeconds) % 60;
135  const auto milSecs =
136  static_cast<unsigned int>(1000 * timeSeconds - floor(timeSeconds));
137 
138  if (nDays > 0) s += mrpt::format("%udays ", nDays);
139  if (nHours > 0) s += mrpt::format("%uh ", nHours);
140  if (nMins > 0) s += mrpt::format("%02umin ", nMins);
141  s += mrpt::format("%02u.%03us", nSecs, milSecs);
142  return s;
143 }
144 
145 static unsigned int calcSecFractions(const uint64_t tmp)
146 {
147  return static_cast<unsigned int>(
148  1e6 * static_cast<double>(tmp % 10000000) / 1e7);
149 }
150 
151 /*---------------------------------------------------------------
152  Convert a timestamp into this textual form: YEAR/MONTH/DAY,HH:MM:SS.MMM
153  ---------------------------------------------------------------*/
155 {
156  if (t == INVALID_TIMESTAMP) return string("INVALID_TIMESTAMP");
157 
158  uint64_t tmp =
159  (t.time_since_epoch().count() - ((uint64_t)116444736 * 1000000000));
160  time_t auxTime = tmp / (uint64_t)10000000;
161  auto secFractions = calcSecFractions(tmp);
162  tm* ptm = gmtime(&auxTime);
163 
164  if (!ptm) return std::string("(Malformed timestamp)");
165 
166  return format(
167  "%u/%02u/%02u,%02u:%02u:%02u.%06u", 1900 + ptm->tm_year,
168  ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min,
169  (unsigned int)ptm->tm_sec, secFractions);
170 }
171 
172 /*---------------------------------------------------------------
173  Convert a timestamp into this textual form (in local time):
174  YEAR/MONTH/DAY,HH:MM:SS.MMM
175  ---------------------------------------------------------------*/
177 {
178  if (t == INVALID_TIMESTAMP) return string("INVALID_TIMESTAMP");
179 
180  uint64_t tmp =
181  (t.time_since_epoch().count() - ((uint64_t)116444736 * 1000000000));
182  time_t auxTime = tmp / (uint64_t)10000000;
183  auto secFractions = calcSecFractions(tmp);
184  tm* ptm = localtime(&auxTime);
185 
186  if (!ptm) return "(Malformed timestamp)";
187 
188  return format(
189  "%u/%02u/%02u,%02u:%02u:%02u.%06u", 1900 + ptm->tm_year,
190  ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min,
191  (unsigned int)ptm->tm_sec, secFractions);
192 }
193 
194 /*---------------------------------------------------------------
195  extractDayTimeFromTimestamp
196  ---------------------------------------------------------------*/
198  const mrpt::system::TTimeStamp tt)
199 {
200  MRPT_START
201  ASSERT_(tt != INVALID_TIMESTAMP);
202 
203  auto t = tt.time_since_epoch().count();
204 #ifdef _WIN32
205  SYSTEMTIME sysT;
206  FileTimeToSystemTime((FILETIME*)&t, &sysT);
207  return sysT.wHour * 3600.0 + sysT.wMinute * 60.0 + sysT.wSecond +
208  sysT.wMilliseconds * 0.001;
209 #else
210  time_t auxTime =
211  (t - ((uint64_t)116444736 * 1000000000)) / (uint64_t)10000000;
212  tm* ptm = gmtime(&auxTime);
213  ASSERTMSG_(ptm, "Malformed timestamp");
214  return ptm->tm_hour * 3600.0 + ptm->tm_min * 60.0 + ptm->tm_sec;
215 #endif
216  MRPT_END
217 }
218 
219 /*---------------------------------------------------------------
220  Convert a timestamp into this textual form: HH:MM:SS.MMM
221  ---------------------------------------------------------------*/
223  const mrpt::system::TTimeStamp tt, unsigned int secondFractionDigits)
224 {
225  if (tt == INVALID_TIMESTAMP) return string("INVALID_TIMESTAMP");
226  auto t = tt.time_since_epoch().count();
227 
228  uint64_t tmp = (t - ((uint64_t)116444736 * 1000000000));
229  const time_t auxTime = tmp / (uint64_t)10000000;
230  const tm* ptm = localtime(&auxTime);
231  auto secFractions = calcSecFractions(tmp);
232  // We start with 10^{-6} second units: reduce if requested by user:
233  const unsigned int user_secondFractionDigits = secondFractionDigits;
234  while (secondFractionDigits++ < 6) secFractions = secFractions / 10;
235 
236  return format(
237  "%02u:%02u:%02u.%0*u", ptm->tm_hour, ptm->tm_min,
238  (unsigned int)ptm->tm_sec, user_secondFractionDigits, secFractions);
239 }
240 
241 /*---------------------------------------------------------------
242  Convert a timestamp into this textual form: HH:MM:SS.MMM
243  ---------------------------------------------------------------*/
245 {
246  if (tt == INVALID_TIMESTAMP) return string("INVALID_TIMESTAMP");
247  auto t = tt.time_since_epoch().count();
248 
249  uint64_t tmp = (t - ((uint64_t)116444736 * 1000000000));
250  time_t auxTime = tmp / (uint64_t)10000000;
251  auto secFractions = calcSecFractions(tmp);
252  tm* ptm = gmtime(&auxTime);
253  if (!ptm) return string("(Malformed timestamp)");
254 
255  return format(
256  "%02u:%02u:%02u.%06u", ptm->tm_hour, ptm->tm_min,
257  (unsigned int)ptm->tm_sec, secFractions);
258 }
259 
260 /*---------------------------------------------------------------
261  Convert a timestamp into this textual form: YEAR/MONTH/DAY
262  ---------------------------------------------------------------*/
264 {
265  if (tt == INVALID_TIMESTAMP) return string("INVALID_TIMESTAMP");
266  auto t = tt.time_since_epoch().count();
267 
268  uint64_t tmp = (t - ((uint64_t)116444736 * 1000000000));
269  time_t auxTime = tmp / (uint64_t)10000000;
270  tm* ptm = gmtime(&auxTime);
271  if (!ptm) return string("(Malformed timestamp)");
272 
273  return format(
274  "%u/%02u/%02u", 1900 + ptm->tm_year, ptm->tm_mon + 1, ptm->tm_mday);
275 }
276 
277 /** This function implements time interval formatting: Given a time in seconds,
278  * it will return a string describing the interval with the most appropriate
279  * unit.
280  * E.g.: 1.23 year, 3.50 days, 9.3 hours, 5.3 minutes, 3.34 sec, 178.1 ms, 87.1
281  * us.
282  */
283 std::string mrpt::system::intervalFormat(const double seconds)
284 {
285  if (seconds >= 365 * 24 * 3600)
286  return format("%.2f years", seconds / (365 * 24 * 3600));
287  else if (seconds >= 24 * 3600)
288  return format("%.2f days", seconds / (24 * 3600));
289  else if (seconds >= 3600)
290  return format("%.2f hours", seconds / 3600);
291  else if (seconds >= 60)
292  return format("%.2f minutes", seconds / 60);
293  else if (seconds >= 1)
294  return format("%.2f sec", seconds);
295  else if (seconds >= 1e-3)
296  return format("%.2f ms", seconds * 1e3);
297  else if (seconds >= 1e-6)
298  return format("%.2f us", seconds * 1e6);
299  else
300  return format("%.2f ns", seconds * 1e9);
301 }
302 
303 std::ostream& mrpt::system::operator<<(std::ostream& o, const TTimeStamp& t)
304 {
305  const uint64_t v = t.time_since_epoch().count();
306  o << v;
307  return o;
308 }
void timestampToParts(TTimeStamp t, TTimeParts &p, bool localTime=false)
Gets the individual parts of a date/time (days, hours, minutes, seconds) - UTC time or local time...
Definition: datetime.cpp:50
std::ostream & operator<<(std::ostream &o, const TTimeStamp &t)
Textual representation of a TTimeStamp as the plain number in time_since_epoch().count() ...
Definition: datetime.cpp:303
#define MRPT_START
Definition: exceptions.h:241
std::string std::string format(std::string_view fmt, ARGS &&... args)
Definition: format.h:26
time_t timegm(struct tm *tm)
An OS-independent version of timegm (which is not present in all compilers): converts a time structur...
Definition: os.cpp:112
mrpt::system::TTimeStamp buildTimestampFromParts(const mrpt::system::TTimeParts &p)
Builds a timestamp from the parts (Parts are in UTC)
Definition: datetime.cpp:74
uint8_t day_of_week
Seconds (0.0000-59.9999)
Definition: datetime.h:57
double extractDayTimeFromTimestamp(const mrpt::system::TTimeStamp t)
Returns the number of seconds ellapsed from midnight in the given timestamp.
Definition: datetime.cpp:197
std::string timeToString(const mrpt::system::TTimeStamp t)
Convert a timestamp into this textual form (UTC): HH:MM:SS.MMMMMM.
Definition: datetime.cpp:244
STL namespace.
std::string formatTimeInterval(const double timeSeconds)
Returns a formated string with the given time difference (passed as the number of seconds)...
Definition: datetime.cpp:124
#define ASSERT_(f)
Defines an assertion mechanism.
Definition: exceptions.h:120
mrpt::Clock::time_point TTimeStamp
A system independent time type, it holds the the number of 100-nanosecond intervals since January 1...
Definition: datetime.h:40
int daylight_saving
Day of week (1:Sunday, 7:Saturday)
Definition: datetime.h:58
std::string dateToString(const mrpt::system::TTimeStamp t)
Convert a timestamp into this textual form: YEAR/MONTH/DAY.
Definition: datetime.cpp:263
The parts of a date/time (it&#39;s like the standard &#39;tm&#39; but with fractions of seconds).
Definition: datetime.h:49
double timestampTotime_t(const mrpt::system::TTimeStamp t) noexcept
Transform from TTimeStamp to standard "time_t" (actually a double number, it can contain fractions of...
Definition: datetime.h:105
std::string intervalFormat(const double seconds)
This function implements time interval formatting: Given a time in seconds, it will return a string d...
Definition: datetime.cpp:283
uint8_t day
Month (1-12)
Definition: datetime.h:53
#define ASSERTMSG_(f, __ERROR_MSG)
Defines an assertion mechanism.
Definition: exceptions.h:108
double second
Minute (0-59)
Definition: datetime.h:56
mrpt::system::TTimeStamp buildTimestampFromPartsLocalTime(const mrpt::system::TTimeParts &p)
Builds a timestamp from the parts (Parts are in local time)
Definition: datetime.cpp:99
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
uint8_t minute
Hour (0-23)
Definition: datetime.h:55
std::string dateTimeToString(const mrpt::system::TTimeStamp t)
Convert a timestamp into this textual form (UTC time): YEAR/MONTH/DAY,HH:MM:SS.MMM.
Definition: datetime.cpp:154
#define MRPT_END
Definition: exceptions.h:245
std::string timeLocalToString(const mrpt::system::TTimeStamp t, unsigned int secondFractionDigits=6)
Convert a timestamp into this textual form (in local time): HH:MM:SS.MMMMMM.
Definition: datetime.cpp:222
uint8_t month
The year.
Definition: datetime.h:52
static unsigned int calcSecFractions(const uint64_t tmp)
Definition: datetime.cpp:145
uint8_t hour
Day (1-31)
Definition: datetime.h:54
std::string dateTimeLocalToString(const mrpt::system::TTimeStamp t)
Convert a timestamp into this textual form (in local time): YEAR/MONTH/DAY,HH:MM:SS.MMM.
Definition: datetime.cpp:176
mrpt::system::TTimeStamp time_tToTimestamp(const double t)
Transform from standard "time_t" (actually a double number, it can contain fractions of seconds) to T...
Definition: datetime.h:91
#define INVALID_TIMESTAMP
Represents an invalid timestamp, where applicable.
Definition: datetime.h:43



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: c7a3bec24 Sun Mar 29 18:33:13 2020 +0200 at dom mar 29 18:50:38 CEST 2020