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