Files
rippled/include/xrpl/basics/chrono.h
2025-11-10 11:49:19 -05:00

110 lines
2.6 KiB
C++

#ifndef XRPL_BASICS_CHRONO_H_INCLUDED
#define XRPL_BASICS_CHRONO_H_INCLUDED
#include <xrpl/beast/clock/abstract_clock.h>
#include <xrpl/beast/clock/basic_seconds_clock.h>
#include <xrpl/beast/clock/manual_clock.h>
#include <date/date.h>
#include <chrono>
#include <cstdint>
#include <ratio>
#include <string>
namespace xrpl {
// A few handy aliases
using days = std::chrono::duration<
int,
std::ratio_multiply<std::chrono::hours::period, std::ratio<24>>>;
using weeks = std::chrono::
duration<int, std::ratio_multiply<days::period, std::ratio<7>>>;
/** Clock for measuring the network time.
The epoch is January 1, 2000
epoch_offset
= date(2000-01-01) - date(1970-0-01)
= days(10957)
= seconds(946684800)
*/
constexpr static std::chrono::seconds epoch_offset =
date::sys_days{date::year{2000} / 1 / 1} -
date::sys_days{date::year{1970} / 1 / 1};
static_assert(epoch_offset.count() == 946684800);
class NetClock
{
public:
explicit NetClock() = default;
using rep = std::uint32_t;
using period = std::ratio<1>;
using duration = std::chrono::duration<rep, period>;
using time_point = std::chrono::time_point<NetClock>;
static bool const is_steady = false;
};
template <class Duration>
std::string
to_string(date::sys_time<Duration> tp)
{
return date::format("%Y-%b-%d %T %Z", tp);
}
inline std::string
to_string(NetClock::time_point tp)
{
// 2000-01-01 00:00:00 UTC is 946684800s from 1970-01-01 00:00:00 UTC
using namespace std::chrono;
return to_string(
system_clock::time_point{tp.time_since_epoch() + epoch_offset});
}
template <class Duration>
std::string
to_string_iso(date::sys_time<Duration> tp)
{
using namespace std::chrono;
return date::format("%FT%TZ", tp);
}
inline std::string
to_string_iso(NetClock::time_point tp)
{
// 2000-01-01 00:00:00 UTC is 946684800s from 1970-01-01 00:00:00 UTC
// Note, NetClock::duration is seconds, as checked by static_assert
static_assert(std::is_same_v<NetClock::duration::period, std::ratio<1>>);
return to_string_iso(date::sys_time<NetClock::duration>{
tp.time_since_epoch() + epoch_offset});
}
/** A clock for measuring elapsed time.
The epoch is unspecified.
*/
using Stopwatch = beast::abstract_clock<std::chrono::steady_clock>;
/** A manual Stopwatch for unit tests. */
using TestStopwatch = beast::manual_clock<std::chrono::steady_clock>;
/** Returns an instance of a wall clock. */
inline Stopwatch&
stopwatch()
{
using Clock = beast::basic_seconds_clock;
using Facade = Clock::Clock;
return beast::get_abstract_clock<Facade, Clock>();
}
} // namespace xrpl
#endif