libfilezilla
time.hpp
Go to the documentation of this file.
1 #ifndef LIBFILEZILLA_TIME_HEADER
2 #define LIBFILEZILLA_TIME_HEADER
3 
4 #include "libfilezilla.hpp"
5 
6 #include <chrono>
7 #include <ctime>
8 
9 #include <limits>
10 
11 #ifdef FZ_WINDOWS
12 #include "glue/windows.hpp"
13 #endif
14 
19 namespace fz {
20 
21 class FZ_PUBLIC_SYMBOL duration;
22 
40 class FZ_PUBLIC_SYMBOL datetime final
41 {
42 public:
46  enum accuracy : char {
47  days,
48  hours,
49  minutes,
50  seconds,
51  milliseconds
52  };
53 
58  enum zone {
59  utc,
60  local
61  };
62 
64  datetime() noexcept = default;
65 
66  datetime(zone z, int year, int month, int day, int hour = -1, int minute = -1, int second = -1, int millisecond = -1);
67 
68  explicit datetime(time_t, accuracy a);
69 
74  explicit datetime(std::string_view const& s, zone z);
75  explicit datetime(std::wstring_view const& s, zone z);
76 
77 #ifdef FZ_WINDOWS
79  explicit datetime(FILETIME const& ft, accuracy a);
80 #endif
81 
82  datetime(datetime const& op) = default;
83  datetime(datetime && op) noexcept = default;
84  datetime& operator=(datetime const& op) = default;
85  datetime& operator=(datetime && op) noexcept = default;
86 
88  bool empty() const;
89 
90  explicit operator bool() const {
91  return !empty();
92  }
93 
95  void clear();
96 
97  accuracy get_accuracy() const { return a_; }
98 
100  static datetime now();
101 
108  bool operator==(datetime const& op) const;
109  bool operator!=(datetime const& op) const { return !(*this == op); }
110  bool operator<(datetime const& op) const;
111  bool operator<=(datetime const& op) const;
112  bool operator>(datetime const& op) const { return op < *this; }
113  bool operator>=(datetime const& op) const { return op <= *this; }
115 
125  int compare(datetime const& op) const;
126 
128  bool earlier_than(datetime const& op) const { return compare(op) < 0; };
129 
131  bool later_than(datetime const& op) const { return compare(op) > 0; };
132 
138  datetime& operator+=(duration const& op);
139  datetime operator+(duration const& op) const { datetime t(*this); t += op; return t; }
140 
141  datetime& operator-=(duration const& op);
142  datetime operator-(duration const& op) const { datetime t(*this); t -= op; return t; }
144 
145  friend duration FZ_PUBLIC_SYMBOL operator-(datetime const& a, datetime const& b);
146 
154  bool set(zone z, int year, int month, int day, int hour = -1, int minute = -1, int second = -1, int millisecond = -1);
155 
165  bool set(std::string_view const& str, zone z);
166  bool set(std::wstring_view const& str, zone z);
167 
168 #ifdef FZ_WINDOWS
170  bool set(FILETIME const& ft, accuracy a);
172  bool set(SYSTEMTIME const& ft, accuracy a, zone z);
173 #endif
174 
175 #if defined(FZ_UNIX) || defined(FZ_MAC)
181  bool set(tm & t, accuracy a, zone z);
182 #endif
183 
190  bool imbue_time(int hour, int minute, int second = -1, int millisecond = -1);
191 
198  std::string format(std::string const& format, zone z) const;
199  std::wstring format(std::wstring const& format, zone z) const;
200 
206  static bool verify_format(std::string const& fmt);
207  static bool verify_format(std::wstring const& fmt);
208 
210  int get_milliseconds() const { return t_ % 1000; }
211 
213  time_t get_time_t() const;
214 
221  tm get_tm(zone z) const;
222 
223 #ifdef FZ_WINDOWS
225  FILETIME get_filetime() const;
226 #endif
227 
234  std::string get_rfc822() const;
235 
251  bool set_rfc822(std::string_view const& str);
252  bool set_rfc822(std::wstring_view const& str);
253 
265  bool set_rfc3339(std::string_view const& str);
266  bool set_rfc3339(std::wstring_view const& str);
267 
268 private:
269  int FZ_PRIVATE_SYMBOL compare_slow(datetime const& op) const;
270 
271  bool FZ_PRIVATE_SYMBOL clamped();
272 
273  enum invalid_t : int64_t {
274  invalid = std::numeric_limits<int64_t>::min()
275  };
276 
277  int64_t t_{invalid};
278  accuracy a_{days};
279 };
280 
290 class FZ_PUBLIC_SYMBOL duration final
291 {
292 public:
293  duration() noexcept = default;
294 
299  int64_t get_days() const { return ms_ / 1000 / 3600 / 24; }
300  int64_t get_hours() const { return ms_ / 1000 / 3600; }
301  int64_t get_minutes() const { return ms_ / 1000 / 60; }
302  int64_t get_seconds() const { return ms_ / 1000; }
303  int64_t get_milliseconds() const { return ms_; }
305 
306  static duration from_days(int64_t m) {
307  return duration(m * 1000 * 60 * 60 * 24);
308  }
309  static duration from_hours(int64_t m) {
310  return duration(m * 1000 * 60 * 60);
311  }
312  static duration from_minutes(int64_t m) {
313  return duration(m * 1000 * 60);
314  }
315  static duration from_seconds(int64_t m) {
316  return duration(m * 1000);
317  }
318  static duration from_milliseconds(int64_t m) {
319  return duration(m);
320  }
322 
323  duration& operator+=(duration const& op) {
324  ms_ += op.ms_;
325  return *this;
326  }
327 
328  duration& operator-=(duration const& op) {
329  ms_ -= op.ms_;
330  return *this;
331  }
332 
333  duration& operator/=(int64_t op) {
334  ms_ /= op;
335  return *this;
336  }
337 
338  duration operator-() const {
339  return duration(-ms_);
340  }
341 
342  explicit operator bool() const {
343  return ms_ != 0;
344  }
345 
346  duration& operator*=(int64_t op) {
347  ms_ *= op;
348  return *this;
349  }
350 
351  duration absolute() const {
352  return (ms_ < 0) ? duration(-ms_) : *this;
353  }
354 
355  bool operator<(duration const& op) const { return ms_ < op.ms_; }
356  bool operator<=(duration const& op) const { return ms_ <= op.ms_; }
357  bool operator>(duration const& op) const { return ms_ > op.ms_; }
358  bool operator>=(duration const& op) const { return ms_ >= op.ms_; }
359 
360  friend duration FZ_PUBLIC_SYMBOL operator-(duration const& a, duration const& b);
361  friend duration FZ_PUBLIC_SYMBOL operator+(duration const& a, duration const& b);
362  friend duration FZ_PUBLIC_SYMBOL operator/(duration const& a, int64_t b);
363 private:
364  explicit FZ_PRIVATE_SYMBOL duration(int64_t ms) : ms_(ms) {}
365 
366  int64_t ms_{};
367 };
368 
369 inline duration operator-(duration const& a, duration const& b)
370 {
371  return duration(a) -= b;
372 }
373 
374 inline duration operator+(duration const& a, duration const& b)
375 {
376  return duration(a) += b;
377 }
378 
379 inline duration operator/(duration const& a, int64_t b)
380 {
381  return duration(a) /= b;
382 }
383 
390 duration FZ_PUBLIC_SYMBOL operator-(datetime const& a, datetime const& b);
391 
392 
393 
394 
402 class FZ_PUBLIC_SYMBOL monotonic_clock final
403 {
404 public:
409  monotonic_clock() = default;
410 
411  monotonic_clock(monotonic_clock const&) = default;
412  monotonic_clock(monotonic_clock &&) noexcept = default;
413  monotonic_clock& operator=(monotonic_clock const&) = default;
414  monotonic_clock& operator=(monotonic_clock &&) noexcept = default;
415 
416  monotonic_clock const operator+(duration const& d) const
417  {
418  return monotonic_clock(*this) += d;
419  }
420  monotonic_clock const operator-(duration const& d) const
421  {
422  return monotonic_clock(*this) += d;
423  }
424 
425 private:
426  typedef std::chrono::steady_clock clock_type;
427  static_assert(std::chrono::steady_clock::is_steady, "Nonconforming stdlib, your steady_clock isn't steady");
428 
429 public:
431  static monotonic_clock now() {
432  return monotonic_clock(clock_type::now());
433  }
434 
435  explicit operator bool() const {
436  return t_ != clock_type::time_point();
437  }
438 
439  monotonic_clock& operator+=(duration const& d)
440  {
441  t_ += std::chrono::milliseconds(d.get_milliseconds());
442  return *this;
443  }
444 
445  monotonic_clock& operator-=(duration const& d)
446  {
447  t_ -= std::chrono::milliseconds(d.get_milliseconds());
448  return *this;
449  }
450 
451 private:
452  explicit FZ_PRIVATE_SYMBOL monotonic_clock(clock_type::time_point const& t)
453  : t_(t)
454  {}
455 
456  clock_type::time_point t_;
457 
458  friend duration operator-(monotonic_clock const& a, monotonic_clock const& b);
459  friend bool operator==(monotonic_clock const& a, monotonic_clock const& b);
460  friend bool operator<(monotonic_clock const& a, monotonic_clock const& b);
461  friend bool operator<=(monotonic_clock const& a, monotonic_clock const& b);
462  friend bool operator>(monotonic_clock const& a, monotonic_clock const& b);
463  friend bool operator>=(monotonic_clock const& a, monotonic_clock const& b);
464 };
465 
470 inline duration operator-(monotonic_clock const& a, monotonic_clock const& b)
471 {
472  return duration::from_milliseconds(std::chrono::duration_cast<std::chrono::milliseconds>(a.t_ - b.t_).count());
473 }
474 
476 inline bool operator==(monotonic_clock const& a, monotonic_clock const& b)
477 {
478  return a.t_ == b.t_;
479 }
480 
482 inline bool operator<(monotonic_clock const& a, monotonic_clock const& b)
483 {
484  return a.t_ < b.t_;
485 }
486 
488 inline bool operator<=(monotonic_clock const& a, monotonic_clock const& b)
489 {
490  return a.t_ <= b.t_;
491 }
492 
494 inline bool operator>(monotonic_clock const& a, monotonic_clock const& b)
495 {
496  return a.t_ > b.t_;
497 }
498 
500 inline bool operator>=(monotonic_clock const& a, monotonic_clock const& b)
501 {
502  return a.t_ >= b.t_;
503 }
504 
505 }
506 
507 #endif
Represents a point of time in wallclock, tracking the timestamps accuracy/precision.
Definition: time.hpp:41
FILETIME get_filetime() const
Windows-only: Get timestamp as FILETIME.
int get_milliseconds() const
Get millisecond part of timestamp.
Definition: time.hpp:210
bool later_than(datetime const &op) const
Equivalent to compare(op) > 0.
Definition: time.hpp:131
bool set(std::string_view const &str, zone z)
Set from string, looks for YYYYmmDD[[[[HH]MM]SS]sss].
accuracy
The datetime's accuracy.
Definition: time.hpp:46
tm get_tm(zone z) const
Get timestamp as struct tm.
bool empty() const
time_t get_time_t() const
Get timestamp as time_t, seconds since 1970-01-01 00:00:00.
bool set(tm &t, accuracy a, zone z)
bool imbue_time(int hour, int minute, int second=-1, int millisecond=-1)
Adds time to timestamps that only have a day-accuracy.
friend duration operator-(datetime const &a, datetime const &b)
Gets the difference between two timestamps as duration.
datetime(FILETIME const &ft, accuracy a)
Windows-only: Construct from FILETIME.
zone
When importing or exporting a timestamp, zone is used to explicitly specify whether the conversion is...
Definition: time.hpp:58
static datetime now()
Returns the current date/time.
bool set_rfc3339(std::string_view const &str)
bool set(FILETIME const &ft, accuracy a)
Windows-only: Set timestamp from FILETIME.
std::string format(std::string const &format, zone z) const
datetime() noexcept=default
A default-constructed timestamp is empty()
bool set(SYSTEMTIME const &ft, accuracy a, zone z)
Windows-only: Set timestamp from SYSTEMTIME.
bool set(zone z, int year, int month, int day, int hour=-1, int minute=-1, int second=-1, int millisecond=-1)
Sets the timestamp.
bool earlier_than(datetime const &op) const
Equivalent to compare(op) < 0.
Definition: time.hpp:128
void clear()
Resulting timestamp is empty()
int compare(datetime const &op) const
Accuracy-aware comparison against another timestamp.
std::string get_rfc822() const
static bool verify_format(std::string const &fmt)
bool set_rfc822(std::string_view const &str)
The duration class represents a time interval in milliseconds.
Definition: time.hpp:291
duration operator-(datetime const &a, datetime const &b)
Gets the difference between two timestamps as duration.
A monotonic clock (aka steady clock) is independent from walltime.
Definition: time.hpp:403
static monotonic_clock now()
Gets the current point in time time.
Definition: time.hpp:431
monotonic_clock()=default
Constructs empty clock.
Sets some global macros and further includes string.hpp.
The namespace used by libfilezilla.
Definition: apply.hpp:17
bool operator==(symmetric_key const &lhs, symmetric_key const &rhs)
Side-channel safe comparison.