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