Jpp in_tag_pdf_generation
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 * Less than method.
133 *
134 * \param object date and time
135 * \result true if this date and time is less than given date and time; else false
136 */
137 inline bool less(const JDateAndTime& object) const
138 {
139 return getElapsedTime(object) > 0.0;
140 }
141
142
143 /**
144 * Smart pointer.
145 *
146 * \return pointer to time structure
147 */
148 const tm* operator->() const
149 {
150 return get();
151 }
152
153
154 /**
155 * Check if UTC time.
156 *
157 * \return true if UTC time; else false
158 */
159 bool isUTC() const
160 {
161 return utc;
162 }
163
164
165 time_t getTime() const { return ts; } //!< time
166
167 int getSeconds() const { return get()->tm_sec; } //!< seconds after the minute [0-59]
168 int getMinutes() const { return get()->tm_min; } //!< minutes after the hour [0-59]
169 int getHour() const { return get()->tm_hour; } //!< hours after midnight [0-23]
170 int getDay() const { return get()->tm_mday; } //!< day of the month [1-31]
171 int getMonth() const { return get()->tm_mon + 1; } //!< month of the year [1-12]
172 int getYear() const { return get()->tm_year + 1900; } //!< year a.d.
173 int getDST() const { return get()->tm_isdst; } //!< daylight saving time
174
175 float getFS() const { return fs; } //!< fraction of second
176
177
178 /**
179 * Get minimum date and time.
180 *
181 * \param utc UTC
182 * \return value
183 */
184 static JDateAndTime min(const bool utc = false)
185 {
186 return JDateAndTime(0, utc);
187 }
188
189
190 /**
191 * Get maximum date and time.
192 *
193 * \param utc UTC
194 * \return value
195 */
196 static JDateAndTime max(const bool utc = false)
197 {
198 return JDateAndTime(std::numeric_limits<time_t>::max(), utc);
199 }
200
201
202 /**
203 * Type conversion operator.
204 *
205 * \return ASCII formatted date and time
206 */
207 operator std::string() const
208 {
209 return this->toString();
210 }
211
212
213 /**
214 * Function to check ISO-8601 conformity.
215 *
216 * \param buffer date and time
217 * \return true if date and time are ISO-8601 conform; else false
218 */
219 inline static bool isISO8601(const std::string& buffer)
220 {
221 using namespace std;
222
223 try {
224
225 JDateAndTime t1(buffer);
226
227 return true;
228 }
229 catch(const std::exception& error) {
230 return false;
231 }
232 }
233
234
235 /**
236 * Get ASCII formatted date and time.
237 *
238 * \return ASCII formatted date and time
239 */
240 inline std::string toString() const
241 {
242 using namespace std;
243
244 static const size_t MAX_SIZE = 256;
245 static char buffer[MAX_SIZE];
246
247 const size_t pos = strftime(buffer, MAX_SIZE, (isUTC() ? "%FT%TZ" : "%FT%T%z"), this->get());
248
249 return string(buffer, pos);
250 }
251
252
253 /**
254 * Set date and time.
255 *
256 * \param utc UTC
257 * \return date and time
258 */
259 inline const JDateAndTime& operator()(const bool utc = false)
260 {
261 set(utc);
262
263 return *this;
264 }
265
266
267 /**
268 * Set to current local time.
269 *
270 * \param utc UTC
271 */
272 void set(const bool utc = false)
273 {
274 time_t tx;
275
276 time(&tx);
277
278 set(tx, utc);
279 }
280
281
282 /**
283 * Set to given time.
284 *
285 * \param t1 time [s]
286 * \param utc UTC
287 */
288 void set(const time_t t1, const bool utc = false)
289 {
290 this->ts = t1;
291 this->utc = utc;
292 }
293
294
295 /**
296 * Set to given time.
297 *
298 * \param t1 time [s]
299 * \param f1 fraction of seconds
300 * \param utc UTC
301 */
302 void set(const time_t t1, const float f1, const bool utc = false)
303 {
304 this->ts = t1;
305 this->fs = f1;
306 this->utc = utc;
307 }
308
309
310 /**
311 * Add given time.
312 *
313 * \param t1 time [s]
314 */
315 void add(const time_t t1)
316 {
317 set(this->ts + t1, this->utc);
318 }
319
320
321 /**
322 * Subtract given time.
323 *
324 * \param t1 time [s]
325 */
326 void sub(const time_t t1)
327 {
328 set(this->ts - t1, this->utc);
329 }
330
331
332 /**
333 * Get elapsed time to given date and time.
334 *
335 * \param object date and time
336 * \return time [s]
337 */
338 double getElapsedTime(const JDateAndTime& object) const
339 {
340 return difftime(object.ts, this->ts) + (object.fs - this->fs);
341 }
342
343
344 /**
345 * Read date and time from input stream.
346 *
347 * \param in input stream
348 * \param object date and time
349 * \return input stream
350 */
351 friend inline std::istream& operator>>(std::istream& in, JDateAndTime& object)
352 {
353 using namespace std;
354
355 const size_t LENGTH = 10; // date may contain '-' and/or be followed by ' '
356
357 string buffer;
358
359 for (int c; (c = in.peek()) != EOF && isspace((char) in.peek()); ) {
360 in.ignore(1);
361 }
362
363 for (int c; (c = in.get()) != EOF && (c != ' ' || buffer.length() == LENGTH); ) {
364 buffer.push_back((char) c);
365 }
366
367 if (in.bad()) {
368 THROW(JIOException, "");
369 }
370
371 // separation of date and time from optional time zone
372
373 size_t pos = string::npos;
374
375 if (pos == string::npos) { pos = buffer.find('Z', LENGTH); } // UTC
376 if (pos == string::npos) { pos = buffer.find('+', LENGTH); } // optional time zone
377 if (pos == string::npos) { pos = buffer.find('-', LENGTH); } // optional time zone
378
379 tm tx;
380 object.fs = 0; // fraction of seconds
381 int nd = 0;
382
383 const string td = buffer.substr(0, pos);
384 const char* pd = NULL;
385
386 switch (td.length()) {
387
388 case 29:
389 case 28:
390 case 27:
391 case 26:
392 case 25:
393 case 24:
394 case 23:
395 case 22:
396 case 21:
397 pd = strptime(td.c_str(), "%Y-%m-%d %H:%M:%S", &tx); sscanf(pd, "%f%n", &object.fs, &nd); pd += nd;
398 break;
399
400 case 19:
401 pd = strptime(td.c_str(), "%Y-%m-%dT%H:%M:%S", &tx);
402 break;
403
404 case 15:
405 pd = strptime(td.c_str(), "%Y%m%dT%H%M%s", &tx);
406 break;
407
408 case 10:
409 pd = strptime(td.c_str(), "%Y-%m-%d", &tx);
410 break;
411 }
412
413 if (pd == NULL || *pd != '\0') {
414 THROW(JParseError, "invalid input <" << buffer << ">");
415 }
416
417 tm ty;
418
419 ty.tm_hour = 0;
420 ty.tm_min = 0;
421
422 if (pos != string::npos && (buffer[pos] == '+' ||
423 buffer[pos] == '-')) {
424
425 const string tz = buffer.substr(pos + 1);
426 const char* pz = tz.c_str();
427
428 switch (tz.length()) {
429
430 case 2:
431 pz = strptime(tz.c_str(), "%H", &ty);
432 break;
433
434 case 4:
435 pz = strptime(tz.c_str(), "%H%M", &ty);
436 break;
437
438 case 5:
439 pz = strptime(tz.c_str(), "%H:%M", &ty);
440 break;
441 }
442
443 if (pz == NULL || *pz != '\0') {
444 THROW(JParseError, "invalid input <" << buffer << ">");
445 }
446 }
447
448 tx.tm_isdst = 0; // switch off day light saving time
449
450 time_t t1 = mktime(&tx);
451
452 t1 -= (ty.tm_hour * 60 + ty.tm_min) * 60; // correct time zone
453 t1 += mktime(localtime(&t1)) - mktime(gmtime(&t1)); //
454
455 object.set(t1, buffer[pos] == 'Z');
456
457 return in;
458 }
459
460
461 /**
462 * Write date and time to output stream.
463 *
464 * \param out output stream
465 * \param object date and time
466 * \return output stream
467 */
468 friend inline std::ostream& operator<<(std::ostream& out, const JDateAndTime& object)
469 {
470 return out << object.toString();
471 }
472
473
474 private:
475
476 /**
477 * Get representation.
478 */
479 tm* get() const
480 {
481 return (this->tp = (utc ? gmtime(&ts) : localtime(&ts)));
482 }
483
484 time_t ts; //!< value
485 float fs = 0.0; //!< fraction of second
486 mutable tm* tp; //!< representation
487 bool utc = false; //!< UTC
488 };
489
490
491 /**
492 * Function object to get current date and time.
493 */
495}
496
497#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]
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.