nidas  v1.2-1520
UTime.h
Go to the documentation of this file.
1 // -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 4; tab-width: 4; -*-
2 // vim: set shiftwidth=4 softtabstop=4 expandtab:
3 /*
4  ********************************************************************
5  ** NIDAS: NCAR In-situ Data Acquistion Software
6  **
7  ** 2006, Copyright University Corporation for Atmospheric Research
8  **
9  ** This program is free software; you can redistribute it and/or modify
10  ** it under the terms of the GNU General Public License as published by
11  ** the Free Software Foundation; either version 2 of the License, or
12  ** (at your option) any later version.
13  **
14  ** This program is distributed in the hope that it will be useful,
15  ** but WITHOUT ANY WARRANTY; without even the implied warranty of
16  ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  ** GNU General Public License for more details.
18  **
19  ** The LICENSE.txt file accompanying this software contains
20  ** a copy of the GNU General Public License. If it is not found,
21  ** write to the Free Software Foundation, Inc.,
22  ** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23  **
24  ********************************************************************
25 */
26 /*
27 
28  C++ class for time handling.
29 
30 */
31 
32 #ifndef NIDAS_UTIL_UTIME_H
33 #define NIDAS_UTIL_UTIME_H
34 
35 #include <sys/types.h>
36 #include <sys/time.h>
37 #include <ctime>
38 #include <iostream>
39 #include <cctype>
40 #include <cmath>
41 #include <climits>
42 
43 #include <locale>
44 #include <string>
45 
46 #include "ThreadSupport.h"
47 #include "ParseException.h"
48 #include "time_constants.h"
49 #include "IOException.h"
50 
60 #define UTIME_BASIC_STREAM_IO
61 
62 namespace nidas { namespace util {
63 
76 class UTime {
77 public:
78 
82  UTime( );
83 
89  UTime(long long t): _utime(t),_fmt(),_utc(true) {}
90 
96  UTime(time_t t): _utime(fromSecs(t)),_fmt(),_utc(true) { }
97 
103  UTime(double t): _utime(fromSecs(t)),_fmt(),_utc(true) { }
104 
108  UTime(bool utc,const struct tm* tmp,int usecs = 0);
109 
115  UTime(bool utc, int year,int mon, int day,int hour, int min, double sec);
116 
122  UTime(bool utc, int year,int yday,int hour, int min, double sec);
123 
124  UTime(const UTime& u) :
125  _utime(u._utime),
126  _fmt(u._fmt),
127  _utc(u._utc)
128  { }
129 
130  void setFromSecs(time_t t) { _utime = fromSecs(t); }
131 
135  struct tm* toTm(bool utc,struct tm* tmp, int* usecs = 0) const;
136 
140  struct tm* toTm(struct tm* tmp, int* usecs = 0) const;
141 
150  static long long fromTm(bool utc,const struct tm* tmp, int usecs = 0);
151 
155  bool isUTC() const { return _utc; }
156 
160  void setUTC(bool val) { _utc = val; }
161 
184  static UTime parse(bool utc, const std::string& string, int* nparsed=0)
185  throw(ParseException);
186 
199  static UTime parse(bool utc, const std::string& string,
200  const std::string& format, int* nparsed=0)
201  throw(ParseException);
202 
206  void set(bool utc,const std::string& string,int* nparsed=0)
207  throw(ParseException);
208 
212  void set(bool utc,const std::string& string,const std::string& format,int* nparsed=0)
213  throw(ParseException);
214 
240  std::string format(bool utc,const std::string& fmt) const;
241 
247  std::string format(const std::string& fmt) const;
248 
253  std::string format(bool utc) const;
254 
260  std::string format() const;
261 
262  UTime& operator=(const UTime& u)
263  {
264  if (this != &u) {
265  _utime = u._utime;
266  _fmt = u._fmt;
267  }
268  return *this;
269  }
270 
271  UTime& operator=(long long u) { _utime = u; return *this; }
272 
273  UTime operator+ (long long u) const { return UTime(_utime + u); }
274 
275  UTime operator- (long long u) const { return UTime(_utime - u); }
276 
277  long long operator- (const UTime& u) const { return _utime - u._utime; }
278 
279  UTime& operator+=(long long u) { _utime += u; return *this; }
280 
281  UTime& operator-=(long long u) { _utime -= u; return *this; }
282 
283  bool operator<(const UTime& u) const { return _utime < u._utime; }
284 
285  bool operator<=(const UTime& u) const { return _utime <= u._utime; }
286 
287  bool operator>(const UTime& u) const { return _utime > u._utime; }
288 
289  bool operator>=(const UTime& u) const { return _utime >= u._utime; }
290 
291  bool operator==(const UTime& u) const { return _utime == u._utime; }
292 
293  bool operator!=(const UTime& u) const { return _utime != u._utime; }
294 
295  UTime earlier(long long y) const;
296 
297  static int month(std::string monstr);
298 
299  // conversion operator
300  // operator long long() const { return _utime; }
301 
302  long long toUsecs() const
303  {
304  return _utime;
305  }
306 
307  double toDoubleSecs() const
308  {
309  // should work for positive and negative.
310  return (time_t)(_utime/USECS_PER_SEC) +
311  (double)(_utime % USECS_PER_SEC) / USECS_PER_SEC;
312  }
313 
314  time_t toSecs() const
315  {
316  return (_utime + USECS_PER_SEC / 2) / USECS_PER_SEC;
317  }
318 
323  UTime& setFormat(const std::string& val)
324  {
325  _fmt = val;
326  return *this;
327  }
328 
334  const std::string& getFormat() const
335  {
336  if (_fmt.length() > 0) return _fmt;
337  return getDefaultFormat();
338  }
339 
344  static void setDefaultFormat(const std::string& val);
345 
346  static const std::string& getDefaultFormat();
347 
352  static void setTZ(const std::string& val);
353 
354  static std::string getTZ();
355 
356  struct tm tm(bool utc) const;
357 
358 #ifdef UTIME_BASIC_STREAM_IO
359  template<typename charT> friend
360  std::basic_ostream<charT, std::char_traits<charT> >& operator <<
361  (std::basic_ostream<charT, std::char_traits<charT> >& os,
362  const UTime& x);
363 #else
364  friend std::ostream& operator<<(std::ostream& os, const UTime &x);
365 #endif
366 
376  static long long pmod(long long x, long long y);
377 
378 protected:
379 
383  static long long fromSecs(time_t x)
384  {
385  return (long long)x * USECS_PER_SEC;
386  }
387 
391  static long long fromSecs(double x)
392  {
393  double xf = floor(x);
394  return (long long)xf * USECS_PER_SEC +
395  (int)rint((x-xf) * USECS_PER_SEC) ;
396  }
397 
398  static double toDoubleSecs(long long x)
399  {
400  // should work for positive and negative.
401  return (time_t)(x/USECS_PER_SEC) + (double)(x % USECS_PER_SEC) / USECS_PER_SEC;
402  }
403 
404  static time_t toSecs(long long x)
405  {
406  return x / USECS_PER_SEC;
407  }
408 
409 private:
410 
416  bool
417  checkParse(bool utc, const std::string& str, const std::string& fmt,
418  int *ncharp, bool throwx=false);
419 
423  long long _utime;
424 
428  std::string _fmt;
429 
434  bool _utc;
435 
436  static std::string _defaultFormat;
437 
438  static Mutex _fmtMutex;
439 
440 };
441 
451 #ifdef UTIME_BASIC_STREAM_IO
452 template<typename charT>
453 #endif
455 
456  std::string _fmt;
457 #ifdef UTIME_BASIC_STREAM_IO
458 
462  std::basic_ostream<charT,std::char_traits<charT> >& (*_f)(std::basic_ostream<charT,std::char_traits<charT> >&, const std::string&);
463 #else
464  std::ostream& (*_f)(std::ostream&, const std::string&);
465 #endif
466 
467 public:
473 #ifdef UTIME_BASIC_STREAM_IO
474  UTime_stream_manip(std::basic_ostream<charT,std::char_traits<charT> >& (*f)(
475  std::basic_ostream<charT,std::char_traits<charT> >&, const std::string&), const std::string& fmt): _fmt(fmt),_f(f)
476  {
477  }
478 #else
479  UTime_stream_manip(std::ostream& (*f)(
480  std::ostream&, const std::string&), const std::string& fmt): _fmt(fmt),_f(f)
481  {
482  }
483 #endif
484 
489 #ifdef UTIME_BASIC_STREAM_IO
490  template<typename charTx>
491  friend std::basic_ostream<charTx, std::char_traits<charTx> >& operator <<
492  (std::basic_ostream<charTx, std::char_traits<charTx> >& os,const UTime_stream_manip<charTx>& m);
493 #else
494  friend std::ostream& operator<<(std::ostream& os,
495  const UTime_stream_manip& m);
496 #endif
497 };
498 
499 #ifdef UTIME_BASIC_STREAM_IO
500 
501 // format a UTime on an output stream.
502 template<typename charT>
503 std::basic_ostream<charT, std::char_traits<charT> >& operator <<
504  (std::basic_ostream<charT, std::char_traits<charT> >& os,const UTime& x)
505 {
506  return os << x.format();
507 }
508 template<typename charT>
509 std::basic_ostream<charT, std::char_traits<charT> >& operator <<
510  (std::basic_ostream<charT, std::char_traits<charT> >& os,const UTime_stream_manip<charT>& m)
511 {
512  return m._f(os,m._fmt);
513 }
514 
515 // anonymous namespace for private, internal functions
516 namespace {
521 template<typename charT>
522 std::basic_ostream<charT, std::char_traits<charT> >&
523  setOstreamDefaultFormat(std::basic_ostream<charT, std::char_traits<charT> >& os,
524  const std::string& val)
525 {
527  return os;
528 }
529 
534 template<typename charT>
535 std::basic_ostream<charT, std::char_traits<charT> >&
536  setOstreamTZ(std::basic_ostream<charT, std::char_traits<charT> >& os,
537  const std::string& val)
538 {
539  UTime::setTZ(val);
540  return os;
541 }
542 } // end of anonymous namespace
543 
547 template<typename charT>
549 {
550  return UTime_stream_manip<charT>(&setOstreamDefaultFormat,val);
551 }
552 
556 template<typename charT>
557 UTime_stream_manip<charT> setTZ(const std::string& val)
558 {
559  return UTime_stream_manip<charT>(&setOstreamTZ,val);
560 }
561 
562 #else
563 
564 std::ostream& operator<<(std::ostream& os, const UTime &x)
565 {
566  return os << x.format(false);
567 }
568 
569 std::ostream& operator<<(std::ostream& os,
570  const UTime_stream_manip& m)
571 {
572  return m._f(os,m._fmt);
573 }
574 
575 // anonymous namespace for private, internal functions
576 namespace {
577 std::ostream& setOstreamDefaultFormat(std::ostream& os, const std::string& val)
578 {
580  return os;
581 }
582 
583 std::ostream& setOstreamTZ(std::ostream& os, const std::string& val)
584 {
585  UTime::setTZ(val);
586  return os;
587 }
588 } // end of anonymous namespace
589 
590 UTime_stream_manip setDefaultFormat(const std::string& val)
591 {
592  return UTime_stream_manip(&setOstreamDefaultFormat,val);
593 }
594 
595 UTime_stream_manip setTZ(const std::string& val)
596 {
597  return UTime_stream_manip(&setOstreamTZ,val);
598 }
599 
600 #endif
601 
606 inline long long getSystemTime() {
607  struct timespec ts;
608  ::clock_gettime(CLOCK_REALTIME,&ts);
609  return (long long)ts.tv_sec * USECS_PER_SEC + ts.tv_nsec / NSECS_PER_USEC;
610 }
611 
619 inline long long timeCeiling(long long t,long long delta) {
620  return ((t / delta) + 1) * delta;
621 }
622 
628 inline long long timeFloor(long long t,long long delta) {
629  return (t / delta) * delta;
630 }
635 extern bool sleepUntil(unsigned int periodMsec,unsigned int offsetMsec=0)
636  throw(IOException);
637 
638 
639 }} // namespace nidas namespace util
640 
641 #endif
bool isUTC() const
Format this UTime relative to UTC, or based on the TZ environment variable.
Definition: UTime.h:155
UTime_stream_manip(std::basic_ostream< charT, std::char_traits< charT > > &(*f)(std::basic_ostream< charT, std::char_traits< charT > > &, const std::string &), const std::string &fmt)
Constructor of manipulator.
Definition: UTime.h:474
friend std::basic_ostream< charTx, std::char_traits< charTx > > & operator<<(std::basic_ostream< charTx, std::char_traits< charTx > > &os, const UTime_stream_manip< charTx > &m)
&lt;&lt; operator of this manipulator on an ostream.
static std::string getTZ()
Definition: UTime.cc:571
static void setTZ(const std::string &val)
Set the TZ environment variable to val.
Definition: UTime.cc:561
static time_t toSecs(long long x)
Definition: UTime.h:404
A class for parsing, formatting and doing operations on time, based on Unix time conventions, where leap seconds are ignored, so that there are always 60 seconds in a minute, 3600 seconds in an hour and 86400 seconds in a day.
Definition: UTime.h:76
#define NSECS_PER_USEC
Definition: types.h:111
std::string _fmt
strftime string to use when formatting this UTime.
Definition: UTime.h:428
static double toDoubleSecs(long long x)
Definition: UTime.h:398
static std::string _defaultFormat
Definition: UTime.h:436
bool operator<=(const UTime &u) const
Definition: UTime.h:285
UTime_stream_manip< charT > setTZ(const std::string &val)
Function to set the UTime timezone on an ostream.
Definition: UTime.h:557
long long getSystemTime()
Return the current unix system time, in microseconds since Jan 1, 1970, 00:00 GMT.
Definition: UTime.h:606
static int month(std::string monstr)
Definition: UTime.cc:581
bool sleepUntil(unsigned int periodMsec, unsigned int offsetMsec=0)
Utility function, sleeps until the next even period + offset.
Definition: UTime.cc:690
bool operator==(const UTime &u) const
Definition: UTime.h:291
void set(bool utc, const std::string &string, int *nparsed=0)
Updates the value of a UTime by doing a parse(utc,string,nparsed).
Definition: UTime.cc:307
long long timeFloor(long long t, long long delta)
Return largest time that is an integral multiple of delta, that isn&#39;t greater than argument t...
Definition: UTime.h:628
UTime(time_t t)
Constructor.
Definition: UTime.h:96
static Mutex _fmtMutex
Definition: UTime.h:438
UTime()
No-arg constructor initializes to current time, with isUTC() true.
Definition: UTime.cc:46
friend std::basic_ostream< charT, std::char_traits< charT > > & operator<<(std::basic_ostream< charT, std::char_traits< charT > > &os, const UTime &x)
Definition: UTime.h:504
static long long fromSecs(time_t x)
Convert a unsigned value in seconds to a value in the units of UTime.
Definition: UTime.h:383
bool operator!=(const UTime &u) const
Definition: UTime.h:293
LogMessage & operator<<(LogMessage &logmsg, LogMessage &(*op)(LogMessage &))
Template to call LogMessage manipulators like endlog when streamed to a LogMessage.
Definition: Logger.h:1062
const std::string & getFormat() const
Get the format used when converting this UTime to a string with format(utc), or format(), or on a ostream.
Definition: UTime.h:334
void setFromSecs(time_t t)
Definition: UTime.h:130
time_t toSecs() const
Definition: UTime.h:314
std::basic_ostream< charT, std::char_traits< charT > > &(* _f)(std::basic_ostream< charT, std::char_traits< charT > > &, const std::string &)
Pointer to function that does a manipulation on a ostream with a string argument. ...
Definition: UTime.h:462
bool operator<(const UTime &u) const
Definition: UTime.h:283
static const std::string & getDefaultFormat()
Definition: UTime.cc:554
UTime & operator-=(long long u)
Definition: UTime.h:281
static long long fromSecs(double x)
Convert a double value in seconds to a value in the units of UTime.
Definition: UTime.h:391
static UTime parse(bool utc, const std::string &string, int *nparsed=0)
Parse a character string into a UTime, using these formats until success:
Definition: UTime.cc:180
std::string format() const
Format a UTime into a string using the format returned by getFormat().
Definition: UTime.cc:427
double toDoubleSecs() const
Definition: UTime.h:307
bool operator>(const UTime &u) const
Definition: UTime.h:287
struct tm tm(bool utc) const
long long toUsecs() const
Definition: UTime.h:302
static long long pmod(long long x, long long y)
Positive modulus: if x &gt; 0, returns x % y else y + (x % y) Useful for time calculation on negative ti...
Definition: UTime.cc:613
static unsigned int periodMsec
Definition: sing.cc:64
UTime & setFormat(const std::string &val)
Set the format used when converting this UTime to a string with format(utc), or format(), or on a ostream.
Definition: UTime.h:323
UTime earlier(long long y) const
Definition: UTime.cc:605
UTime operator-(long long u) const
Definition: UTime.h:275
UTime(double t)
Constructor.
Definition: UTime.h:103
struct tm * toTm(bool utc, struct tm *tmp, int *usecs=0) const
Set values in a struct tm from a UTime.
Definition: UTime.cc:163
UTime operator+(long long u) const
Definition: UTime.h:273
UTime(const UTime &u)
Definition: UTime.h:124
UTime & operator+=(long long u)
Definition: UTime.h:279
bool checkParse(bool utc, const std::string &str, const std::string &fmt, int *ncharp, bool throwx=false)
Parse into this UTime same as parse(), returning true on success.
Definition: UTime.cc:331
bool _utc
Whether to format this UTime relative to UTC.
Definition: UTime.h:434
long long _utime
non-leap micro-seconds since 1970 Jan 1 00:00 UTC.
Definition: UTime.h:423
class for changing output format of UTime on ostream, in a way like the standard stream manipulator c...
Definition: UTime.h:454
#define USECS_PER_SEC
Definition: ublox.cc:59
long long timeCeiling(long long t, long long delta)
Return smallest time that is an integral multiple of delta, that isn&#39;t less than or equal to argument...
Definition: UTime.h:619
bool operator>=(const UTime &u) const
Definition: UTime.h:289
UTime_stream_manip< charT > setDefaultFormat(const std::string &val)
Function to set the default UTime output format on an ostream.
Definition: UTime.h:548
void setUTC(bool val)
Format this UTime relative to UTC, or the local timezone?
Definition: UTime.h:160
UTime(long long t)
Constructor.
Definition: UTime.h:89
static long long fromTm(bool utc, const struct tm *tmp, int usecs=0)
Return number of non-leap micro-seconds since Jan 1970 00:00 UTC computed from time fields in a struc...
Definition: UTime.cc:111
A C++ wrapper for a POSIX mutex.
Definition: ThreadSupport.h:154
static void setDefaultFormat(const std::string &val)
Static method to set the default output format.
Definition: UTime.cc:548
LogMessage & format(const char *fmt,...)
Definition: Logger.cc:561
std::string _fmt
Definition: UTime.h:456
UTime & operator=(long long u)
Definition: UTime.h:271
Definition: ParseException.h:36