CDT  v4.2.0
инструменты разработчика
time.hpp
См. документацию.
1#pragma once
2#include <stdint.h>
3#include <string>
4#include <chrono>
5#include <ctime>
6#include <cstdio>
7#include "check.hpp"
8#include "serialize.hpp"
9
10namespace eosio {
20 public:
21 explicit microseconds( int64_t c = 0) :_count(c){}
22
24 static microseconds maximum() { return microseconds(0x7fffffffffffffffll); }
25 friend microseconds operator + (const microseconds& l, const microseconds& r ) { return microseconds(l._count+r._count); }
26 friend microseconds operator - (const microseconds& l, const microseconds& r ) { return microseconds(l._count-r._count); }
27
28
29 bool operator==(const microseconds& c)const { return _count == c._count; }
30 bool operator!=(const microseconds& c)const { return _count != c._count; }
31 friend bool operator>(const microseconds& a, const microseconds& b){ return a._count > b._count; }
32 friend bool operator>=(const microseconds& a, const microseconds& b){ return a._count >= b._count; }
33 friend bool operator<(const microseconds& a, const microseconds& b){ return a._count < b._count; }
34 friend bool operator<=(const microseconds& a, const microseconds& b){ return a._count <= b._count; }
35 microseconds& operator+=(const microseconds& c) { _count += c._count; return *this; }
36 microseconds& operator-=(const microseconds& c) { _count -= c._count; return *this; }
37 int64_t count()const { return _count; }
38 int64_t to_seconds()const { return _count/1000000; }
39
40 int64_t _count;
43 private:
44 friend class time_point;
45 };
46
47 inline microseconds seconds( int64_t s ) { return microseconds( s * 1000000 ); }
48 inline microseconds milliseconds( int64_t s ) { return microseconds( s * 1000 ); }
49 inline microseconds minutes(int64_t m) { return seconds(60*m); }
50 inline microseconds hours(int64_t h) { return minutes(60*h); }
51 inline microseconds days(int64_t d) { return hours(24*d); }
52
58 class time_point {
59 public:
60 explicit time_point( microseconds e = microseconds() ) :elapsed(e){}
61 const microseconds& time_since_epoch()const { return elapsed; }
62 uint32_t sec_since_epoch()const { return uint32_t(elapsed.count() / 1000000); }
63
64 static time_point from_iso_string(const std::string& date_str) {
65 std::tm tm;
66 check(strptime(date_str.c_str(), "%Y-%m-%dT%H:%M:%S", &tm), "date parsing failed");
67
68 auto tp = std::chrono::system_clock::from_time_t( ::mktime( &tm ) );
69 auto duration = std::chrono::duration_cast<std::chrono::microseconds>( tp.time_since_epoch() );
70 return time_point{ microseconds{ static_cast<int64_t>(duration.count()) } };
71 }
72
73 std::string to_string() const {
74 time_t rawtime = sec_since_epoch();
75
76 char buf[100];
77 strftime(buf, sizeof(buf), "%Y-%m-%dT%H:%M:%S", gmtime ( &rawtime ));
78
79 return std::string{buf};
80 }
81
83 bool operator > ( const time_point& t )const { return elapsed._count > t.elapsed._count; }
84 bool operator >=( const time_point& t )const { return elapsed._count >=t.elapsed._count; }
85 bool operator < ( const time_point& t )const { return elapsed._count < t.elapsed._count; }
86 bool operator <=( const time_point& t )const { return elapsed._count <=t.elapsed._count; }
87 bool operator ==( const time_point& t )const { return elapsed._count ==t.elapsed._count; }
88 bool operator !=( const time_point& t )const { return elapsed._count !=t.elapsed._count; }
89 time_point& operator += ( const microseconds& m) { elapsed+=m; return *this; }
90 time_point& operator -= ( const microseconds& m) { elapsed-=m; return *this; }
91 time_point operator + (const microseconds& m) const { return time_point(elapsed+m); }
92 time_point operator + (const time_point& m) const { return time_point(elapsed+m.elapsed); }
93 time_point operator - (const microseconds& m) const { return time_point(elapsed-m); }
94 microseconds operator - (const time_point& m) const { return microseconds(elapsed.count() - m.elapsed.count()); }
95 microseconds elapsed;
97
98 EOSLIB_SERIALIZE( time_point, (elapsed) )
99 };
100
107 {
108 public:
110 :utc_seconds(0){}
111
113 :utc_seconds(seconds){}
114
116 :utc_seconds( uint32_t(t.time_since_epoch().count() / 1000000ll) ){}
117
118 static time_point_sec maximum() { return time_point_sec(0xffffffff); }
119 static time_point_sec min() { return time_point_sec(0); }
120
121 static time_point_sec from_iso_string(const std::string& date_str) {
122 auto time_p = time_point::from_iso_string(date_str);
123 return time_point_sec{ time_p };
124 }
125
126 std::string to_string() const {
127 return ((time_point)(*this)).to_string();
128 }
129
130 operator time_point()const { return time_point( eosio::seconds( utc_seconds) ); }
131 uint32_t sec_since_epoch()const { return utc_seconds; }
132
134 time_point_sec operator = ( const eosio::time_point& t )
135 {
136 utc_seconds = uint32_t(t.time_since_epoch().count() / 1000000ll);
137 return *this;
138 }
139 friend bool operator < ( const time_point_sec& a, const time_point_sec& b ) { return a.utc_seconds < b.utc_seconds; }
140 friend bool operator > ( const time_point_sec& a, const time_point_sec& b ) { return a.utc_seconds > b.utc_seconds; }
141 friend bool operator <= ( const time_point_sec& a, const time_point_sec& b ) { return a.utc_seconds <= b.utc_seconds; }
142 friend bool operator >= ( const time_point_sec& a, const time_point_sec& b ) { return a.utc_seconds >= b.utc_seconds; }
143 friend bool operator == ( const time_point_sec& a, const time_point_sec& b ) { return a.utc_seconds == b.utc_seconds; }
144 friend bool operator != ( const time_point_sec& a, const time_point_sec& b ) { return a.utc_seconds != b.utc_seconds; }
145 time_point_sec& operator += ( uint32_t m ) { utc_seconds+=m; return *this; }
146 time_point_sec& operator += ( microseconds m ) { utc_seconds+=m.to_seconds(); return *this; }
147 time_point_sec& operator += ( time_point_sec m ) { utc_seconds+=m.utc_seconds; return *this; }
148 time_point_sec& operator -= ( uint32_t m ) { utc_seconds-=m; return *this; }
149 time_point_sec& operator -= ( microseconds m ) { utc_seconds-=m.to_seconds(); return *this; }
150 time_point_sec& operator -= ( time_point_sec m ) { utc_seconds-=m.utc_seconds; return *this; }
151 time_point_sec operator +( uint32_t offset )const { return time_point_sec(utc_seconds + offset); }
152 time_point_sec operator -( uint32_t offset )const { return time_point_sec(utc_seconds - offset); }
153
154 friend time_point operator + ( const time_point_sec& t, const microseconds& m ) { return time_point(t) + m; }
155 friend time_point operator - ( const time_point_sec& t, const microseconds& m ) { return time_point(t) - m; }
156 friend microseconds operator - ( const time_point_sec& t, const time_point_sec& m ) { return time_point(t) - time_point(m); }
157 friend microseconds operator - ( const time_point& t, const time_point_sec& m ) { return time_point(t) - time_point(m); }
158 uint32_t utc_seconds;
159
161
162 EOSLIB_SERIALIZE( time_point_sec, (utc_seconds) )
163 };
164
172 public:
173 explicit block_timestamp( uint32_t s=0 ) :slot(s){}
174
176 set_time_point(t);
177 }
178
180 set_time_point(t);
181 }
182
183 static block_timestamp maximum() { return block_timestamp( 0xffff ); }
184 static block_timestamp min() { return block_timestamp(0); }
185
187 eosio::check( std::numeric_limits<uint32_t>::max() - slot >= 1, "block timestamp overflow" );
188 auto result = block_timestamp(*this);
189 result.slot += 1;
190 return result;
191 }
192
194 return (time_point)(*this);
195 }
196
197 operator time_point() const {
198 int64_t msec = slot * (int64_t)block_interval_ms;
199 msec += block_timestamp_epoch;
200 return time_point(milliseconds(msec));
201 }
202
203 static block_timestamp from_iso_string(const std::string& date_str) {
204 auto time_p = time_point::from_iso_string(date_str);
205 return block_timestamp{ time_p };
206 }
207
208 std::string to_string() const {
209 return to_time_point().to_string();
210 }
211
213 void operator = (const time_point& t ) {
214 set_time_point(t);
215 }
216
217 bool operator > ( const block_timestamp& t )const { return slot > t.slot; }
218 bool operator >=( const block_timestamp& t )const { return slot >= t.slot; }
219 bool operator < ( const block_timestamp& t )const { return slot < t.slot; }
220 bool operator <=( const block_timestamp& t )const { return slot <= t.slot; }
221 bool operator ==( const block_timestamp& t )const { return slot == t.slot; }
222 bool operator !=( const block_timestamp& t )const { return slot != t.slot; }
223 uint32_t slot;
224 static constexpr int32_t block_interval_ms = 500;
225 static constexpr int64_t block_timestamp_epoch = 946684800000ll; // эпоха — 1 января 2000 UTC (мс)
227
229 private:
230
231
232 void set_time_point(const time_point& t) {
233 int64_t micro_since_epoch = t.time_since_epoch().count();
234 int64_t msec_since_epoch = micro_since_epoch / 1000;
235 slot = uint32_t(( msec_since_epoch - block_timestamp_epoch ) / int64_t(block_interval_ms));
236 }
237
238 void set_time_point(const time_point_sec& t) {
239 int64_t sec_since_epoch = t.sec_since_epoch();
240 slot = uint32_t((sec_since_epoch * 1000 - block_timestamp_epoch) / block_interval_ms);
241 }
242 }; // block_timestamp
243
248
249} // namespace eosio