hmbdc
simplify-high-performance-messaging-programming
Time.hpp
1 #include "hmbdc/Copyright.hpp"
2 #pragma once
3 
4 #include "hmbdc/Endian.hpp"
5 #include <sys/time.h>
6 #include <iostream>
7 #include <stdio.h>
8 #include <stdint.h>
9 #include <time.h>
10 #include <limits>
11 
12 namespace hmbdc { namespace time {
13 struct Duration;
14 struct SysTime
15 {
16  SysTime() : nsecSinceEpoch_(0){}
17  ///UTC as input
18  explicit SysTime(int64_t sec, int64_t usec = 0, int64_t nsec = 0) {
19  nsecSinceEpoch_ = sec * 1000000000l + usec*1000l + nsec;
20  }
21 
22  static SysTime now() {
23  struct timespec spec;
24  clock_gettime(CLOCK_REALTIME, &spec);
25  return SysTime(spec.tv_sec, 0, spec.tv_nsec);
26  }
27 
28  int64_t usecSinceEpoch() const { return nsecSinceEpoch_ / 1000l; }
29  Duration sinceMidnight() const;
30  SysTime previousMidnight() const;
31 
32  bool operator < (SysTime const& other) const {
33  return nsecSinceEpoch_ < other.nsecSinceEpoch_;
34  }
35 
36  bool operator <= (SysTime const& other) const {
37  return nsecSinceEpoch_ <= other.nsecSinceEpoch_;
38  }
39 
40  bool operator > (SysTime const& other) const {
41  return nsecSinceEpoch_ > other.nsecSinceEpoch_;
42  }
43 
44  bool operator >= (SysTime const& other) const {
45  return nsecSinceEpoch_ >= other.nsecSinceEpoch_;
46  }
47  bool operator == (SysTime const& other) const {
48  return nsecSinceEpoch_ == other.nsecSinceEpoch_;
49  }
50 
51  Duration operator - (SysTime const&) const;
52  SysTime operator + (Duration const&) const;
53  SysTime operator - (Duration const&) const;
54 
55  static
56  SysTime
57  fromYYYYMMDDhhmmSSmmmUtc(int64_t v) {
58  struct tm v_tm = {0};
59  v_tm.tm_year = static_cast<int>(v/10000000000000l);
60  v %= 10000000000000l;
61  v_tm.tm_year -= 1900;
62  v_tm.tm_mon = static_cast<int>(v/100000000000l);
63  v %= 100000000000l;
64  v_tm.tm_mon -= 1;
65  v_tm.tm_mday = static_cast<int>(v/1000000000l);
66  v %= 1000000000l;
67  v_tm.tm_hour = static_cast<int>(v/10000000l);
68  v %= 10000000l;
69  v_tm.tm_min = static_cast<int>(v/100000l);
70  v %= 100000l;
71  v_tm.tm_sec = static_cast<int>(v/1000l);
72  v %= 1000l;
73  v_tm.tm_isdst = -1;
74  return SysTime(timegm(&v_tm), v * 1000l);
75  }
76 
77  static
78  SysTime
79  fromYYYYMMDDhhmmSSmmm(int64_t v) {
80  struct tm v_tm = {0};
81  v_tm.tm_year = static_cast<int>(v/10000000000000l);
82  v %= 10000000000000l;
83  v_tm.tm_year -= 1900;
84  v_tm.tm_mon = static_cast<int>(v/100000000000l);
85  v %= 100000000000l;
86  v_tm.tm_mon -= 1;
87  v_tm.tm_mday = static_cast<int>(v/1000000000l);
88  v %= 1000000000l;
89  v_tm.tm_hour = static_cast<int>(v/10000000l);
90  v %= 10000000l;
91  v_tm.tm_min = static_cast<int>(v/100000l);
92  v %= 100000l;
93  v_tm.tm_sec = static_cast<int>(v/1000l);
94  v %= 1000l;
95  v_tm.tm_isdst = -1;
96  return SysTime(mktime(&v_tm), v * 1000l);
97  }
98 
99  void toXmitEndian() {
100  nsecSinceEpoch_ = Endian::toXmit(nsecSinceEpoch_);
101  }
102 
103  void toNativeEndian() {
104  toXmitEndian();
105  }
106 
107 private:
108  int64_t nsecSinceEpoch_;
109  friend std::ostream& operator << (std::ostream& os, SysTime const& t);
110 };
111 
112 inline
113 std::ostream& operator << (std::ostream& os, SysTime const& t) {
114  char buf[32];
115  char buf2[32];
116  tm ts;
117  time_t sec = (time_t)(t.nsecSinceEpoch_ / 1000000000ll);
118  localtime_r(&sec, &ts);
119  strftime(buf, sizeof(buf), "%Y%m%d%H%M%S.", &ts);
120  sprintf(buf2, "%09lld", t.nsecSinceEpoch_ % 1000000000ll);
121  os << buf << buf2;
122  return os;
123 }
124 
125 struct Duration {
126  Duration() : nsec_(0){}
127  static Duration seconds(int64_t sec) {return Duration(sec);}
128 
129  static Duration milliseconds(int64_t msec) {return Duration(0, msec * 1000);}
130 
131  static Duration microseconds(int64_t usec) { return Duration(0, usec); }
132 
133  static Duration nanoseconds(int64_t nsec) { return Duration(0, 0, nsec); }
134 
135  explicit Duration(int64_t sec, int64_t usec = 0, int64_t nsec = 0) {
136  nsec_ = sec * 1000000000l + usec * 1000l + nsec;}
137 
138  int64_t milliseconds() const { return nsec_ / 1000000l; }
139  int64_t microseconds() const { return nsec_ / 1000l; }
140  int64_t nanoseconds() const { return nsec_; }
141 
142  explicit operator bool() const {
143  return nsec_;
144  }
145 
146  explicit operator double() const {
147  return (double)nsec_ / 1000000000.0;
148  }
149 
150  bool operator < (Duration const& other) const { return nsec_ < other.nsec_; }
151  bool operator > (Duration const& other) const { return nsec_ > other.nsec_; }
152  bool operator == (Duration const& other) const { return nsec_ == other.nsec_; }
153  bool operator >= (Duration const& other) const { return nsec_ >= other.nsec_; }
154  bool operator <= (Duration const& other) const { return nsec_ <= other.nsec_; }
155 
156  Duration& operator += (Duration const& other) {
157  nsec_ += other.nsec_;
158  return *this;
159  }
160 
161  Duration operator - () const {
162  return nanoseconds(-nsec_);
163  }
164 
165  Duration operator - (Duration const& other) const {
166  return nanoseconds(nsec_ - other.nsec_);
167  }
168 
169  Duration operator + (Duration const& other) const {
170  return nanoseconds(nsec_ + other.nsec_);
171  }
172 
173  Duration& operator -= (Duration const& other) {
174  nsec_ -= other.nsec_;
175  return *this;
176  }
177  double operator / (Duration const& other) const {
178  return (double)nsec_ / other.nsec_;
179  }
180 
181  Duration operator * (int64_t m) const {
182  return Duration(0, 0, nsec_ * m);
183  }
184 
185  Duration operator / (int64_t const& d) const {
186  return Duration(0, 0, nsec_ / d);
187  }
188 
189  Duration operator % (Duration const& d) const {
190  return Duration(0, 0, nsec_ % d.nsec_);
191  }
192 
193  void toXmitEndian() {
194  nsec_ = Endian::toXmit(nsec_);
195  }
196 
197  void toNativeEndian() {
198  toXmitEndian();
199  }
200 
201 private:
202  friend struct SysTime;
203  friend std::ostream& operator <<
204  (std::ostream& os, Duration const& d);
205  friend std::istream& operator >>
206  (std::istream& is, Duration& d);
207 
208  int64_t nsec_;
209 };
210 
211 inline
212 Duration
213 SysTime::
214 operator - (SysTime const& b) const {
215  return Duration::nanoseconds(nsecSinceEpoch_
216  - b.nsecSinceEpoch_);
217 }
218 
219 inline
220 SysTime
221 SysTime::
222 operator + (Duration const& d) const {
223  return SysTime(0, 0, nsecSinceEpoch_ + d.nsec_);
224 }
225 
226 inline
227 SysTime
228 SysTime::
229 operator - (Duration const& d) const {
230  return SysTime(0, 0, nsecSinceEpoch_ - d.nsec_);
231 }
232 
233 inline
234 Duration
235 SysTime::
236 sinceMidnight() const {
237  return *this - previousMidnight();
238 }
239 
240 inline
241 SysTime
242 SysTime::
243 previousMidnight() const {
244  tm ts;
245  time_t sec = (time_t)(nsecSinceEpoch_ / 1000000000l);
246  localtime_r(&sec, &ts);
247  return SysTime(sec) - Duration(ts.tm_hour * 3600 + ts.tm_min * 60 + ts.tm_sec);
248 }
249 
250 inline
251 SysTime&
252 operator += (SysTime & t, Duration const& d) {
253  t = t + d;
254  return t;
255 }
256 
257 inline
258 SysTime&
259 operator -= (SysTime & t, Duration const& d) {
260  t = t - d;
261  return t;
262 }
263 
264 inline
265 std::ostream&
266 operator << (std::ostream& os, Duration const& d) {
267  char buf[32];
268  if (d.nsec_ >= 0) {
269  sprintf(buf, "%09lld", d.nsec_ % 1000000000ll);
270  os << d.nsec_ / 1000000000l << '.' << buf;
271  } else {
272  sprintf(buf, "%09lld", (-d.nsec_) % 1000000000ll);
273  os << '-' << (-d.nsec_) / 1000000000l << '.' << buf;
274  }
275 
276  return os;
277 }
278 
279 
280 inline
281 std::istream&
282 operator >> (std::istream& is, Duration& d) {
283  double t;
284  is >> t;
285  d.nsec_ = (int64_t)(t * 1000000000l);
286  return is;
287 }
288 
289 }}
290 
291 namespace std {
292 template <>
293 struct numeric_limits<hmbdc::time::Duration> : numeric_limits<int64_t> {
294 public:
295  static hmbdc::time::Duration min() throw()
296  {return hmbdc::time::Duration::nanoseconds(numeric_limits<int64_t>::min());}
297  static hmbdc::time::Duration max() throw()
298  {return hmbdc::time::Duration::nanoseconds(numeric_limits<int64_t>::max());}
299 };
300 }
Definition: TypedString.hpp:74
SysTime(int64_t sec, int64_t usec=0, int64_t nsec=0)
UTC as input.
Definition: Time.hpp:18
Definition: Time.hpp:14
Definition: Time.hpp:125
Definition: Base.hpp:12