Jpp 20.0.0-rc.2
the software that should make you happy
Loading...
Searching...
No Matches
JDateAndTime.hh
Go to the documentation of this file.
1#ifndef __JSYSTEM__JDATEANDTIME__
2#define __JSYSTEM__JDATEANDTIME__
3
4#include <istream>
5#include <ostream>
6#include <sstream>
7#include <limits>
8#include <string>
9#include <string.h>
10#include <time.h>
11
12#include "JLang/JComparable.hh"
13#include "JLang/JException.hh"
14
15
16/**
17 * \file
18 * Date and time functions.
19 *
20 * \author mdejong, bjung
21 */
22namespace JSYSTEM {}
23namespace JPP { using namespace JSYSTEM; }
24
25namespace JSYSTEM {
26
30
31
32 /**
33 * Get current local date conform ISO-8601 standard.
34 *
35 * \return date
36 */
37 inline const char* getDate()
38 {
39 static time_t ts;
40 static const size_t MAX_SIZE = 256;
41 static char buffer[MAX_SIZE];
42
43 time(&ts);
44
45 strftime(buffer, MAX_SIZE, "%F", localtime(&ts));
46
47 return buffer;
48 }
49
50
51 /**
52 * Get current local time conform ISO-8601 standard.
53 *
54 * \return time
55 */
56 inline const char* getTime()
57 {
58 static time_t ts;
59 static const size_t MAX_SIZE = 256;
60 static char buffer[MAX_SIZE];
61
62 time(&ts);
63
64 strftime(buffer, MAX_SIZE, "%T%z", localtime(&ts));
65
66 return buffer;
67 }
68
69
70 /**
71 * Auxiliary class for date and time.
72 *
73 * The data structure <tt>time_t</tt> is used for the internal value and
74 * the data structure <tt>tm</tt> for the representation.
75 *
76 * The I/O format conforms with ISO-8601 standard
77 * but it is also possible to parse <tt>ROOT TTimeStamp::AsString("c")</tt>.
78 */
79 struct JDateAndTime :
80 JComparable<JDateAndTime>
81 {
82 /**
83 * Constructor.
84 *
85 * \param utc UTC
86 */
87 JDateAndTime(const bool utc = false)
88 {
89 set(utc);
90 }
91
92
93 /**
94 * Constructor.
95 *
96 * \param t1 time [s]
97 * \param utc UTC
98 */
99 JDateAndTime(const time_t t1, const bool utc = false)
100 {
101 set(t1, utc);
102 }
103
104
105 /**
106 * Constructor.
107 *
108 * \param t1 time [s]
109 * \param f1 fraction of seconds
110 * \param utc UTC
111 */
112 JDateAndTime(const time_t t1, const float f1, const bool utc = false)
113 {
114 set(t1, f1, utc);
115 }
116
117
118 /**
119 * Constructor.
120 *
121 * \param buffer date and time
122 */
123 JDateAndTime(const std::string& buffer)
124 {
125 std::istringstream is(buffer);
126
127 is >> *this;
128 }
129
130
131 /**
132 * Constructor.
133 *
134 * \param buffer date and time
135 */
136 JDateAndTime(const char* const buffer)
137 {
138 std::istringstream is(buffer);
139
140 is >> *this;
141 }
142
143
144 /**
145 * Less than method.
146 *
147 * \param object date and time
148 * \result true if this date and time is less than given date and time; else false
149 */
150 inline bool less(const JDateAndTime& object) const
151 {
152 return getElapsedTime(object) > 0.0;
153 }
154
155
156 /**
157 * Smart pointer.
158 *
159 * \return pointer to time structure
160 */
161 const tm* operator->() const
162 {
163 return get();
164 }
165
166
167 /**
168 * Check if UTC time.
169 *
170 * \return true if UTC time; else false
171 */
172 bool isUTC() const
173 {
174 return utc;
175 }
176
177
178 time_t getTime() const { return ts; } //!< time
179
180 int getSeconds() const { return get()->tm_sec; } //!< seconds after the minute [0-59]
181 int getMinutes() const { return get()->tm_min; } //!< minutes after the hour [0-59]
182 int getHour() const { return get()->tm_hour; } //!< hours after midnight [0-23]
183 int getDay() const { return get()->tm_mday; } //!< day of the month [1-31]
184 int getMonth() const { return get()->tm_mon + 1; } //!< month of the year [1-12]
185 int getYear() const { return get()->tm_year + 1900; } //!< year a.d.
186 int getDST() const { return get()->tm_isdst; } //!< daylight saving time
187
188 float getFS() const { return fs; } //!< fraction of second
189
190
191 /**
192 * Get minimum date and time.
193 *
194 * \param utc UTC
195 * \return value
196 */
197 static JDateAndTime min(const bool utc = false)
198 {
199 return JDateAndTime(0, utc);
200 }
201
202
203 /**
204 * Get maximum date and time.
205 *
206 * \param utc UTC
207 * \return value
208 */
209 static JDateAndTime max(const bool utc = false)
210 {
211 return JDateAndTime(std::numeric_limits<time_t>::max(), utc);
212 }
213
214
215 /**
216 * Type conversion operator.
217 *
218 * \return ASCII formatted date and time
219 */
220 operator std::string() const
221 {
222 return this->toString();
223 }
224
225
226 /**
227 * Function to check ISO-8601 conformity.
228 *
229 * \param buffer date and time
230 * \return true if date and time are ISO-8601 conform; else false
231 */
232 inline static bool isISO8601(const std::string& buffer)
233 {
234 using namespace std;
235
236 try {
237
238 JDateAndTime t1(buffer);
239
240 return true;
241 }
242 catch(const std::exception& error) {
243 return false;
244 }
245 }
246
247
248 /**
249 * Get ASCII formatted date and time.
250 *
251 * \return ASCII formatted date and time
252 */
253 inline std::string toString() const
254 {
255 using namespace std;
256
257 static const size_t MAX_SIZE = 256;
258 static char buffer[MAX_SIZE];
259
260 const size_t pos = strftime(buffer, MAX_SIZE, (isUTC() ? "%FT%TZ" : "%FT%T%z"), this->get());
261
262 return string(buffer, pos);
263 }
264
265
266 /**
267 * Set date and time.
268 *
269 * \param utc UTC
270 * \return date and time
271 */
272 inline const JDateAndTime& operator()(const bool utc = false)
273 {
274 set(utc);
275
276 return *this;
277 }
278
279
280 /**
281 * Set to current local time.
282 *
283 * \param utc UTC
284 */
285 void set(const bool utc = false)
286 {
287 time_t tx;
288
289 time(&tx);
290
291 set(tx, utc);
292 }
293
294
295 /**
296 * Set to given time.
297 *
298 * \param t1 time [s]
299 * \param utc UTC
300 */
301 void set(const time_t t1, const bool utc = false)
302 {
303 this->ts = t1;
304 this->utc = utc;
305 }
306
307
308 /**
309 * Set to given time.
310 *
311 * \param t1 time [s]
312 * \param f1 fraction of seconds
313 * \param utc UTC
314 */
315 void set(const time_t t1, const float f1, const bool utc = false)
316 {
317 this->ts = t1;
318 this->fs = f1;
319 this->utc = utc;
320 }
321
322
323 /**
324 * Add given time.
325 *
326 * \param t1 time [s]
327 */
328 void add(const time_t t1)
329 {
330 set(this->ts + t1, this->utc);
331 }
332
333
334 /**
335 * Subtract given time.
336 *
337 * \param t1 time [s]
338 */
339 void sub(const time_t t1)
340 {
341 set(this->ts - t1, this->utc);
342 }
343
344
345 /**
346 * Get elapsed time to given date and time.
347 *
348 * \param object date and time
349 * \return time [s]
350 */
351 double getElapsedTime(const JDateAndTime& object) const
352 {
353 return difftime(object.ts, this->ts) + (object.fs - this->fs);
354 }
355
356
357 /**
358 * Read date and time from input stream.
359 *
360 * \param in input stream
361 * \param object date and time
362 * \return input stream
363 */
364 friend inline std::istream& operator>>(std::istream& in, JDateAndTime& object)
365 {
366 using namespace std;
367
368 const size_t LENGTH = 10; // date may contain '-' and/or be followed by ' '
369
370 string buffer;
371
372 for (int c; (c = in.peek()) != EOF && isspace((char) in.peek()); ) {
373 in.ignore(1);
374 }
375
376 for (int c; (c = in.get()) != EOF && (c != ' ' || buffer.length() == LENGTH); ) {
377 buffer.push_back((char) c);
378 }
379
380 if (in.bad()) {
381 THROW(JIOException, "");
382 }
383
384 // separation of date and time from optional time zone
385
386 size_t pos = string::npos;
387
388 if (pos == string::npos) { pos = buffer.find('Z', LENGTH); } // UTC
389 if (pos == string::npos) { pos = buffer.find('+', LENGTH); } // optional time zone
390 if (pos == string::npos) { pos = buffer.find('-', LENGTH); } // optional time zone
391
392 tm tx;
393 object.fs = 0; // fraction of seconds
394 int nd = 0;
395
396 const string td = buffer.substr(0, pos);
397 const char* pd = NULL;
398
399 switch (td.length()) {
400
401 case 29:
402 case 28:
403 case 27:
404 case 26:
405 case 25:
406 case 24:
407 case 23:
408 case 22:
409 case 21:
410 pd = strptime(td.c_str(), "%Y-%m-%d %H:%M:%S", &tx); sscanf(pd, "%f%n", &object.fs, &nd); pd += nd;
411 break;
412
413 case 19:
414 pd = strptime(td.c_str(), "%Y-%m-%dT%H:%M:%S", &tx);
415 break;
416
417 case 15:
418 pd = strptime(td.c_str(), "%Y%m%dT%H%M%s", &tx);
419 break;
420
421 case 10:
422 pd = strptime(td.c_str(), "%Y-%m-%d", &tx);
423 break;
424 }
425
426 if (pd == NULL || *pd != '\0') {
427 THROW(JParseError, "invalid input <" << buffer << ">");
428 }
429
430 tm ty;
431
432 ty.tm_hour = 0;
433 ty.tm_min = 0;
434
435 if (pos != string::npos && (buffer[pos] == '+' ||
436 buffer[pos] == '-')) {
437
438 const string tz = buffer.substr(pos + 1);
439 const char* pz = tz.c_str();
440
441 switch (tz.length()) {
442
443 case 2:
444 pz = strptime(tz.c_str(), "%H", &ty);
445 break;
446
447 case 4:
448 pz = strptime(tz.c_str(), "%H%M", &ty);
449 break;
450
451 case 5:
452 pz = strptime(tz.c_str(), "%H:%M", &ty);
453 break;
454 }
455
456 if (pz == NULL || *pz != '\0') {
457 THROW(JParseError, "invalid input <" << buffer << ">");
458 }
459 }
460
461 tx.tm_isdst = 0; // switch off day light saving time
462
463 time_t t1 = mktime(&tx);
464
465 t1 -= (ty.tm_hour * 60 + ty.tm_min) * 60; // correct time zone
466 t1 += mktime(localtime(&t1)) - mktime(gmtime(&t1)); //
467
468 object.set(t1, buffer[pos] == 'Z');
469
470 return in;
471 }
472
473
474 /**
475 * Write date and time to output stream.
476 *
477 * \param out output stream
478 * \param object date and time
479 * \return output stream
480 */
481 friend inline std::ostream& operator<<(std::ostream& out, const JDateAndTime& object)
482 {
483 return out << object.toString();
484 }
485
486
487 private:
488
489 /**
490 * Get representation.
491 */
492 tm* get() const
493 {
494 return (this->tp = (utc ? gmtime(&ts) : localtime(&ts)));
495 }
496
497 time_t ts; //!< value
498 float fs = 0.0; //!< fraction of second
499 mutable tm* tp; //!< representation
500 bool utc = false; //!< UTC
501 };
502
503
504 /**
505 * Function object to get current date and time.
506 */
508}
509
510#endif
Exceptions.
#define THROW(JException_t, A)
Marco for throwing exception with std::ostream compatible message.
Exception for I/O.
Exception for parsing value.
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
Auxiliary classes and methods for operating system calls.
const char * getTime()
Get current local time conform ISO-8601 standard.
const char * getDate()
Get current local date conform ISO-8601 standard.
static JDateAndTime getDateAndTime
Function object to get current date and time.
Template definition of auxiliary base class for comparison of data structures.
Auxiliary class for date and time.
JDateAndTime(const bool utc=false)
Constructor.
bool isUTC() const
Check if UTC time.
friend std::ostream & operator<<(std::ostream &out, const JDateAndTime &object)
Write date and time to output stream.
double getElapsedTime(const JDateAndTime &object) const
Get elapsed time to given date and time.
JDateAndTime(const std::string &buffer)
Constructor.
std::string toString() const
Get ASCII formatted date and time.
JDateAndTime(const time_t t1, const float f1, const bool utc=false)
Constructor.
int getMinutes() const
minutes after the hour [0-59]
int getYear() const
year a.d.
time_t getTime() const
time
int getHour() const
hours after midnight [0-23]
int getDST() const
daylight saving time
void set(const bool utc=false)
Set to current local time.
bool less(const JDateAndTime &object) const
Less than method.
int getDay() const
day of the month [1-31]
JDateAndTime(const char *const buffer)
Constructor.
tm * tp
representation
float getFS() const
fraction of second
const tm * operator->() const
Smart pointer.
int getMonth() const
month of the year [1-12]
JDateAndTime(const time_t t1, const bool utc=false)
Constructor.
static bool isISO8601(const std::string &buffer)
Function to check ISO-8601 conformity.
int getSeconds() const
seconds after the minute [0-59]
void set(const time_t t1, const bool utc=false)
Set to given time.
tm * get() const
Get representation.
friend std::istream & operator>>(std::istream &in, JDateAndTime &object)
Read date and time from input stream.
void sub(const time_t t1)
Subtract given time.
void add(const time_t t1)
Add given time.
static JDateAndTime min(const bool utc=false)
Get minimum date and time.
float fs
fraction of second
const JDateAndTime & operator()(const bool utc=false)
Set date and time.
operator std::string() const
Type conversion operator.
void set(const time_t t1, const float f1, const bool utc=false)
Set to given time.
static JDateAndTime max(const bool utc=false)
Get maximum date and time.