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