time.h raw

   1  // Copyright (c) 2009-2010 Satoshi Nakamoto
   2  // Copyright (c) 2009-present The Bitcoin Core developers
   3  // Distributed under the MIT software license, see the accompanying
   4  // file COPYING or http://www.opensource.org/licenses/mit-license.php.
   5  
   6  #ifndef BITCOIN_UTIL_TIME_H
   7  #define BITCOIN_UTIL_TIME_H
   8  
   9  // The `util/time.h` header is designed to be a drop-in replacement for `chrono`.
  10  #include <chrono> // IWYU pragma: export
  11  #include <cstdint>
  12  #include <ctime>
  13  #include <optional>
  14  #include <string>
  15  #include <string_view>
  16  
  17  #ifdef WIN32
  18  #include <winsock2.h>
  19  #else
  20  #include <sys/time.h>
  21  #endif
  22  
  23  using namespace std::chrono_literals;
  24  
  25  /// Version of the system clock that is mockable in the context of tests (via
  26  /// FakeNodeClock or ::SetMockTime), otherwise the system clock.
  27  struct NodeClock : public std::chrono::system_clock {
  28      using time_point = std::chrono::time_point<NodeClock>;
  29      /** Return current system time or mocked time, if set */
  30      static time_point now() noexcept;
  31      static std::time_t to_time_t(const time_point&) = delete; // unused
  32      static time_point from_time_t(std::time_t) = delete;      // unused
  33      static constexpr time_point epoch{};
  34  };
  35  using NodeSeconds = std::chrono::time_point<NodeClock, std::chrono::seconds>;
  36  
  37  using SteadyClock = std::chrono::steady_clock;
  38  using SteadySeconds = std::chrono::time_point<std::chrono::steady_clock, std::chrono::seconds>;
  39  using SteadyMilliseconds = std::chrono::time_point<std::chrono::steady_clock, std::chrono::milliseconds>;
  40  using SteadyMicroseconds = std::chrono::time_point<std::chrono::steady_clock, std::chrono::microseconds>;
  41  
  42  using SystemClock = std::chrono::system_clock;
  43  
  44  /// Version of SteadyClock that is mockable in the context of tests (via
  45  /// FakeSteadyClock, or Self::SetMockTime), otherwise the system steady
  46  /// clock.
  47  struct MockableSteadyClock : public std::chrono::steady_clock {
  48      using time_point = std::chrono::time_point<MockableSteadyClock>;
  49  
  50      using mock_time_point = std::chrono::time_point<MockableSteadyClock, std::chrono::milliseconds>;
  51      static constexpr mock_time_point::duration INITIAL_MOCK_TIME{1};
  52  
  53      /** Return current system time or mocked time, if set */
  54      static time_point now() noexcept;
  55      static std::time_t to_time_t(const time_point&) = delete; // unused
  56      static time_point from_time_t(std::time_t) = delete;      // unused
  57  
  58      /** Set mock time for testing.
  59       * When mocking the steady clock, start at INITIAL_MOCK_TIME and add durations to elapse time as necessary
  60       * for testing.
  61       * To stop mocking, call ClearMockTime().
  62       */
  63      static void SetMockTime(mock_time_point::duration mock_time_in);
  64  
  65      /** Clear mock time, go back to system steady clock. */
  66      static void ClearMockTime();
  67  };
  68  
  69  void UninterruptibleSleep(const std::chrono::microseconds& n);
  70  
  71  /**
  72   * Helper to count the seconds of a duration/time_point.
  73   *
  74   * All durations/time_points should be using std::chrono and calling this should generally
  75   * be avoided in code. Though, it is still preferred to an inline t.count() to
  76   * protect against a reliance on the exact type of t.
  77   *
  78   * This helper is used to convert durations/time_points before passing them over an
  79   * interface that doesn't support std::chrono (e.g. RPC, debug log, or the GUI)
  80   */
  81  template <typename Dur1, typename Dur2>
  82  constexpr auto Ticks(Dur2 d)
  83  {
  84      return std::chrono::duration_cast<Dur1>(d).count();
  85  }
  86  
  87  template <typename Duration>
  88  constexpr int64_t TicksSeconds(Duration d)
  89  {
  90      return int64_t{Ticks<std::chrono::seconds>(d)};
  91  }
  92  template <typename Duration, typename Timepoint>
  93  constexpr auto TicksSinceEpoch(Timepoint t)
  94  {
  95      return Ticks<Duration>(t.time_since_epoch());
  96  }
  97  constexpr int64_t count_seconds(std::chrono::seconds t) { return t.count(); }
  98  constexpr int64_t count_milliseconds(std::chrono::milliseconds t) { return t.count(); }
  99  constexpr int64_t count_microseconds(std::chrono::microseconds t) { return t.count(); }
 100  
 101  using HoursDouble = std::chrono::duration<double, std::chrono::hours::period>;
 102  using SecondsDouble = std::chrono::duration<double, std::chrono::seconds::period>;
 103  using MillisecondsDouble = std::chrono::duration<double, std::chrono::milliseconds::period>;
 104  
 105  /**
 106   * DEPRECATED
 107   * Use either ClockType::now() or Now<TimePointType>() if a cast is needed.
 108   * ClockType is
 109   * - SteadyClock/std::chrono::steady_clock for steady time
 110   * - SystemClock/std::chrono::system_clock for system time
 111   * - NodeClock                             for mockable system time
 112   */
 113  int64_t GetTime();
 114  
 115  /**
 116   * DEPRECATED
 117   * Use SetMockTime with chrono type
 118   *
 119   * @param[in] nMockTimeIn Time in seconds.
 120   */
 121  void SetMockTime(int64_t nMockTimeIn);
 122  
 123  /** For testing. Set e.g. with the setmocktime rpc, or -mocktime argument */
 124  void SetMockTime(std::chrono::seconds mock_time_in);
 125  void SetMockTime(std::chrono::time_point<NodeClock, std::chrono::seconds> mock);
 126  
 127  /** For testing */
 128  std::chrono::seconds GetMockTime();
 129  
 130  /**
 131   * Return the current time point cast to the given precision. Only use this
 132   * when an exact precision is needed, otherwise use T::clock::now() directly.
 133   */
 134  template <typename T>
 135  T Now()
 136  {
 137      return std::chrono::time_point_cast<typename T::duration>(T::clock::now());
 138  }
 139  /** DEPRECATED, see GetTime */
 140  template <typename T>
 141  T GetTime()
 142  {
 143      return Now<std::chrono::time_point<NodeClock, T>>().time_since_epoch();
 144  }
 145  
 146  /**
 147   * ISO 8601 formatting is preferred. Use the FormatISO8601{DateTime,Date}
 148   * helper functions if possible.
 149   */
 150  std::string FormatISO8601DateTime(int64_t nTime);
 151  std::string FormatISO8601Date(int64_t nTime);
 152  std::optional<int64_t> ParseISO8601DateTime(std::string_view str);
 153  
 154  /**
 155   * RFC1123 formatting https://www.rfc-editor.org/rfc/rfc1123#section-5.2.14
 156   * Used in HTTP/1.1 responses
 157   */
 158  std::string FormatRFC1123DateTime(int64_t nTime);
 159  
 160  /**
 161   * Convert milliseconds to a struct timeval for e.g. select.
 162   */
 163  struct timeval MillisToTimeval(int64_t nTimeout);
 164  
 165  /**
 166   * Convert milliseconds to a struct timeval for e.g. select.
 167   */
 168  struct timeval MillisToTimeval(std::chrono::milliseconds ms);
 169  
 170  #endif // BITCOIN_UTIL_TIME_H
 171