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 microseconds(int64_t usec) { return Duration(0, usec); }
130 
131  static Duration nanoseconds(int64_t nsec) { return Duration(0, 0, nsec); }
132 
133  explicit Duration(int64_t sec, int64_t usec = 0, int64_t nsec = 0) {
134  nsec_ = sec * 1000000000l + usec * 1000l + nsec;}
135 
136  int64_t microseconds() const { return nsec_ / 1000l; }
137  int64_t nanoseconds() const { return nsec_; }
138 
139  explicit operator bool() const {
140  return nsec_;
141  }
142 
143  explicit operator double() const {
144  return (double)nsec_ / 1000000000.0;
145  }
146 
147  bool operator < (Duration const& other) const { return nsec_ < other.nsec_; }
148  bool operator > (Duration const& other) const { return nsec_ > other.nsec_; }
149  bool operator == (Duration const& other) const { return nsec_ == other.nsec_; }
150  bool operator >= (Duration const& other) const { return nsec_ >= other.nsec_; }
151  bool operator <= (Duration const& other) const { return nsec_ <= other.nsec_; }
152 
153  Duration& operator += (Duration const& other) {
154  nsec_ += other.nsec_;
155  return *this;
156  }
157 
158  Duration operator - () const {
159  return nanoseconds(-nsec_);
160  }
161 
162  Duration operator - (Duration const& other) const {
163  return nanoseconds(nsec_ - other.nsec_);
164  }
165 
166  Duration operator + (Duration const& other) const {
167  return nanoseconds(nsec_ + other.nsec_);
168  }
169 
170  Duration& operator -= (Duration const& other) {
171  nsec_ -= other.nsec_;
172  return *this;
173  }
174  double operator / (Duration const& other) const {
175  return (double)nsec_ / other.nsec_;
176  }
177 
178  Duration operator * (int64_t m) const {
179  return Duration(0, 0, nsec_ * m);
180  }
181 
182  Duration operator / (int64_t const& d) const {
183  return Duration(0, 0, nsec_ / d);
184  }
185 
186  Duration operator % (Duration const& d) const {
187  return Duration(0, 0, nsec_ % d.nsec_);
188  }
189 
190  void toXmitEndian() {
191  nsec_ = Endian::toXmit(nsec_);
192  }
193 
194  void toNativeEndian() {
195  toXmitEndian();
196  }
197 
198 private:
199  friend struct SysTime;
200  friend std::ostream& operator <<
201  (std::ostream& os, Duration const& d);
202  friend std::istream& operator >>
203  (std::istream& is, Duration& d);
204 
205  int64_t nsec_;
206 };
207 
208 inline
209 Duration
210 SysTime::
211 operator - (SysTime const& b) const {
212  return Duration::nanoseconds(nsecSinceEpoch_
213  - b.nsecSinceEpoch_);
214 }
215 
216 inline
217 SysTime
218 SysTime::
219 operator + (Duration const& d) const {
220  return SysTime(0, 0, nsecSinceEpoch_ + d.nsec_);
221 }
222 
223 inline
224 SysTime
225 SysTime::
226 operator - (Duration const& d) const {
227  return SysTime(0, 0, nsecSinceEpoch_ - d.nsec_);
228 }
229 
230 inline
231 Duration
232 SysTime::
233 sinceMidnight() const {
234  return *this - previousMidnight();
235 }
236 
237 inline
238 SysTime
239 SysTime::
240 previousMidnight() const {
241  tm ts;
242  time_t sec = (time_t)(nsecSinceEpoch_ / 1000000000l);
243  localtime_r(&sec, &ts);
244  return SysTime(sec) - Duration(ts.tm_hour * 3600 + ts.tm_min * 60 + ts.tm_sec);
245 }
246 
247 inline
248 SysTime&
249 operator += (SysTime & t, Duration const& d) {
250  t = t + d;
251  return t;
252 }
253 
254 inline
255 SysTime&
256 operator -= (SysTime & t, Duration const& d) {
257  t = t - d;
258  return t;
259 }
260 
261 inline
262 std::ostream&
263 operator << (std::ostream& os, Duration const& d) {
264  char buf[32];
265  if (d.nsec_ >= 0) {
266  sprintf(buf, "%09lld", d.nsec_ % 1000000000ll);
267  os << d.nsec_ / 1000000000l << '.' << buf;
268  } else {
269  sprintf(buf, "%09lld", (-d.nsec_) % 1000000000ll);
270  os << '-' << (-d.nsec_) / 1000000000l << '.' << buf;
271  }
272 
273  return os;
274 }
275 
276 
277 inline
278 std::istream&
279 operator >> (std::istream& is, Duration& d) {
280  double t;
281  is >> t;
282  d.nsec_ = (int64_t)(t * 1000000000l);
283  return is;
284 }
285 
286 }}
287 
288 namespace std {
289 template <>
290 struct numeric_limits<hmbdc::time::Duration> : numeric_limits<int64_t> {
291 public:
292  static hmbdc::time::Duration min() throw()
293  {return hmbdc::time::Duration::nanoseconds(numeric_limits<int64_t>::min());}
294  static hmbdc::time::Duration max() throw()
295  {return hmbdc::time::Duration::nanoseconds(numeric_limits<int64_t>::max());}
296 };
297 }
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