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