![]() |
libfilezilla
|
00001 #ifndef LIBFILEZILLA_TIME_HEADER 00002 #define LIBFILEZILLA_TIME_HEADER 00003 00004 #include "libfilezilla.hpp" 00005 00006 #include <chrono> 00007 #include <ctime> 00008 00009 #include <limits> 00010 00011 #ifdef FZ_WINDOWS 00012 #include "private/windows.hpp" 00013 #endif 00014 00019 namespace fz { 00020 00021 class FZ_PUBLIC_SYMBOL duration; 00022 00040 class FZ_PUBLIC_SYMBOL datetime final 00041 { 00042 public: 00046 enum accuracy : char { 00047 days, 00048 hours, 00049 minutes, 00050 seconds, 00051 milliseconds 00052 }; 00053 00058 enum zone { 00059 utc, 00060 local 00061 }; 00062 00064 datetime() = default; 00065 00066 datetime(zone z, int year, int month, int day, int hour = -1, int minute = -1, int second = -1, int millisecond = -1); 00067 00068 explicit datetime(time_t, accuracy a); 00069 00074 explicit datetime(std::string const& s, zone z); 00075 explicit datetime(std::wstring const& s, zone z); 00076 00077 #ifdef FZ_WINDOWS 00078 00079 explicit datetime(FILETIME const& ft, accuracy a); 00080 #endif 00081 00082 datetime(datetime const& op) = default; 00083 datetime(datetime && op) noexcept = default; 00084 datetime& operator=(datetime const& op) = default; 00085 datetime& operator=(datetime && op) noexcept = default; 00086 00088 bool empty() const; 00089 00091 void clear(); 00092 00093 accuracy get_accuracy() const { return a_; } 00094 00096 static datetime now(); 00097 00104 bool operator==(datetime const& op) const; 00105 bool operator!=(datetime const& op) const { return !(*this == op); } 00106 bool operator<(datetime const& op) const; 00107 bool operator<=(datetime const& op) const; 00108 bool operator>(datetime const& op) const { return op < *this; } 00110 00120 int compare(datetime const& op) const; 00121 00123 bool earlier_than(datetime const& op) const { return compare(op) < 0; }; 00124 00126 bool later_than(datetime const& op) const { return compare(op) > 0; }; 00127 00133 datetime& operator+=(duration const& op); 00134 datetime operator+(duration const& op) const { datetime t(*this); t += op; return t; } 00135 00136 datetime& operator-=(duration const& op); 00137 datetime operator-(duration const& op) const { datetime t(*this); t -= op; return t; } 00139 00140 friend duration FZ_PUBLIC_SYMBOL operator-(datetime const& a, datetime const& b); 00141 00149 bool set(zone z, int year, int month, int day, int hour = -1, int minute = -1, int second = -1, int millisecond = -1); 00150 00160 bool set(std::string const& str, zone z); 00161 bool set(std::wstring const& str, zone z); 00162 00163 #ifdef FZ_WINDOWS 00164 00165 bool set(FILETIME const& ft, accuracy a); 00167 bool set(SYSTEMTIME const& ft, accuracy a, zone z); 00168 #endif 00169 00170 #if defined(FZ_UNIX) || defined(FZ_MAC) 00171 00176 bool set(tm & t, accuracy a, zone z); 00177 #endif 00178 00185 bool imbue_time(int hour, int minute, int second = -1, int millisecond = -1); 00186 00191 std::string format(std::string const& format, zone z) const; 00192 std::wstring format(std::wstring const& format, zone z) const; 00193 00199 static bool verify_format(std::string const& fmt); 00200 static bool verify_format(std::wstring const& fmt); 00201 00203 int get_milliseconds() const { return t_ % 1000; } 00204 00206 time_t get_time_t() const; 00207 00209 tm get_tm(zone z) const; 00210 00211 #ifdef FZ_WINDOWS 00212 00213 FILETIME get_filetime() const; 00214 #endif 00215 00216 private: 00217 int FZ_PRIVATE_SYMBOL compare_slow(datetime const& op) const; 00218 00219 bool FZ_PRIVATE_SYMBOL clamped(); 00220 00221 enum invalid_t : int64_t { 00222 invalid = std::numeric_limits<int64_t>::min() 00223 }; 00224 00225 int64_t t_{invalid}; 00226 accuracy a_{days}; 00227 }; 00228 00236 class FZ_PUBLIC_SYMBOL duration final 00237 { 00238 public: 00239 duration() = default; 00240 00245 int64_t get_days() const { return ms_ / 1000 / 3600 / 24; } 00246 int64_t get_hours() const { return ms_ / 1000 / 3600; } 00247 int64_t get_minutes() const { return ms_ / 1000 / 60; } 00248 int64_t get_seconds() const { return ms_ / 1000; } 00249 int64_t get_milliseconds() const { return ms_; } 00251 00252 static duration from_days(int64_t m) { 00253 return duration(m * 1000 * 60 * 60 * 24); 00254 } 00255 static duration from_hours(int64_t m) { 00256 return duration(m * 1000 * 60 * 60); 00257 } 00258 static duration from_minutes(int64_t m) { 00259 return duration(m * 1000 * 60); 00260 } 00261 static duration from_seconds(int64_t m) { 00262 return duration(m * 1000); 00263 } 00264 static duration from_milliseconds(int64_t m) { 00265 return duration(m); 00266 } 00268 00269 duration& operator-=(duration const& op) { 00270 ms_ -= op.ms_; 00271 return *this; 00272 } 00273 00274 duration operator-() const { 00275 return duration(-ms_); 00276 } 00277 00278 explicit operator bool() const { 00279 return ms_ != 0; 00280 } 00281 00282 bool operator<(duration const& op) const { return ms_ < op.ms_; } 00283 bool operator<=(duration const& op) const { return ms_ <= op.ms_; } 00284 bool operator>(duration const& op) const { return ms_ > op.ms_; } 00285 bool operator>=(duration const& op) const { return ms_ >= op.ms_; } 00286 00287 friend duration FZ_PUBLIC_SYMBOL operator-(duration const& a, duration const& b); 00288 private: 00289 explicit duration(int64_t ms) : ms_(ms) {} 00290 00291 int64_t ms_{}; 00292 }; 00293 00294 inline duration operator-(duration const& a, duration const& b) 00295 { 00296 return duration(a) -= b; 00297 } 00298 00299 00306 duration FZ_PUBLIC_SYMBOL operator-(datetime const& a, datetime const& b); 00307 00308 00309 00310 00318 class FZ_PUBLIC_SYMBOL monotonic_clock final 00319 { 00320 public: 00325 monotonic_clock() = default; 00326 00327 monotonic_clock(monotonic_clock const&) = default; 00328 monotonic_clock(monotonic_clock &&) noexcept = default; 00329 monotonic_clock& operator=(monotonic_clock const&) = default; 00330 monotonic_clock& operator=(monotonic_clock &&) noexcept = default; 00331 00332 monotonic_clock const operator+(duration const& d) const 00333 { 00334 return monotonic_clock(*this) += d; 00335 } 00336 00337 private: 00338 typedef std::chrono::steady_clock clock_type; 00339 static_assert(std::chrono::steady_clock::is_steady, "Nonconforming stdlib, your steady_clock isn't steady"); 00340 00341 public: 00343 static monotonic_clock now() { 00344 return monotonic_clock(clock_type::now()); 00345 } 00346 00347 explicit operator bool() const { 00348 return t_ != clock_type::time_point(); 00349 } 00350 00351 monotonic_clock& operator+=(duration const& d) 00352 { 00353 t_ += std::chrono::milliseconds(d.get_milliseconds()); 00354 return *this; 00355 } 00356 00357 monotonic_clock& operator-=(duration const& d) 00358 { 00359 t_ -= std::chrono::milliseconds(d.get_milliseconds()); 00360 return *this; 00361 } 00362 00363 private: 00364 explicit monotonic_clock(clock_type::time_point const& t) 00365 : t_(t) 00366 {} 00367 00368 clock_type::time_point t_; 00369 00370 friend duration operator-(monotonic_clock const& a, monotonic_clock const& b); 00371 friend bool operator==(monotonic_clock const& a, monotonic_clock const& b); 00372 friend bool operator<(monotonic_clock const& a, monotonic_clock const& b); 00373 friend bool operator<=(monotonic_clock const& a, monotonic_clock const& b); 00374 friend bool operator>(monotonic_clock const& a, monotonic_clock const& b); 00375 friend bool operator>=(monotonic_clock const& a, monotonic_clock const& b); 00376 }; 00377 00382 inline duration operator-(monotonic_clock const& a, monotonic_clock const& b) 00383 { 00384 return duration::from_milliseconds(std::chrono::duration_cast<std::chrono::milliseconds>(a.t_ - b.t_).count()); 00385 } 00386 00388 inline bool operator==(monotonic_clock const& a, monotonic_clock const& b) 00389 { 00390 return a.t_ == b.t_; 00391 } 00392 00394 inline bool operator<(monotonic_clock const& a, monotonic_clock const& b) 00395 { 00396 return a.t_ < b.t_; 00397 } 00398 00400 inline bool operator<=(monotonic_clock const& a, monotonic_clock const& b) 00401 { 00402 return a.t_ <= b.t_; 00403 } 00404 00406 inline bool operator>(monotonic_clock const& a, monotonic_clock const& b) 00407 { 00408 return a.t_ > b.t_; 00409 } 00410 00412 inline bool operator>=(monotonic_clock const& a, monotonic_clock const& b) 00413 { 00414 return a.t_ >= b.t_; 00415 } 00416 00417 } 00418 00419 #endif