-
Notifications
You must be signed in to change notification settings - Fork 405
Expand file tree
/
Copy pathtime.cpp
More file actions
130 lines (113 loc) · 4.43 KB
/
Copy pathtime.cpp
File metadata and controls
130 lines (113 loc) · 4.43 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <util/time.h>
#include <compat/compat.h>
#include <tinyformat.h>
#include <util/check.h>
#include <util/strencodings.h>
#include <atomic>
#include <chrono>
#include <optional>
#include <string>
#include <string_view>
#include <thread>
void UninterruptibleSleep(const std::chrono::microseconds& n) { std::this_thread::sleep_for(n); }
static std::atomic<std::chrono::seconds> g_mock_time{}; //!< For testing
std::atomic<bool> g_used_system_time{false};
static std::atomic<std::chrono::milliseconds> g_mock_steady_time{}; //!< For testing
NodeClock::time_point NodeClock::now() noexcept
{
const auto mocktime{g_mock_time.load(std::memory_order_relaxed)};
if (!mocktime.count()) {
g_used_system_time = true;
}
const auto ret{
mocktime.count() ?
mocktime :
std::chrono::system_clock::now().time_since_epoch()};
assert(ret > 0s);
return time_point{ret};
};
void SetMockTime(int64_t nMockTimeIn) { SetMockTime(std::chrono::seconds{nMockTimeIn}); }
void SetMockTime(std::chrono::seconds mock_time_in)
{
Assert(mock_time_in >= 0s);
g_mock_time.store(mock_time_in, std::memory_order_relaxed);
}
std::chrono::seconds GetMockTime()
{
return g_mock_time.load(std::memory_order_relaxed);
}
MockableSteadyClock::time_point MockableSteadyClock::now() noexcept
{
const auto mocktime{g_mock_steady_time.load(std::memory_order_relaxed)};
if (!mocktime.count()) {
g_used_system_time = true;
}
const auto ret{
mocktime.count() ?
mocktime :
std::chrono::steady_clock::now().time_since_epoch()};
return time_point{ret};
};
void MockableSteadyClock::SetMockTime(std::chrono::milliseconds mock_time_in)
{
Assert(mock_time_in >= 0s);
g_mock_steady_time.store(mock_time_in, std::memory_order_relaxed);
}
void MockableSteadyClock::ClearMockTime()
{
g_mock_steady_time.store(0ms, std::memory_order_relaxed);
}
int64_t GetTime() { return GetTime<std::chrono::seconds>().count(); }
std::string FormatISO8601DateTime(int64_t nTime)
{
const std::chrono::sys_seconds secs{std::chrono::seconds{nTime}};
const auto days{std::chrono::floor<std::chrono::days>(secs)};
const std::chrono::year_month_day ymd{days};
const std::chrono::hh_mm_ss hms{secs - days};
return strprintf("%04i-%02u-%02uT%02i:%02i:%02iZ", signed{ymd.year()}, unsigned{ymd.month()}, unsigned{ymd.day()}, hms.hours().count(), hms.minutes().count(), hms.seconds().count());
}
std::string FormatISO8601Date(int64_t nTime)
{
const std::chrono::sys_seconds secs{std::chrono::seconds{nTime}};
const auto days{std::chrono::floor<std::chrono::days>(secs)};
const std::chrono::year_month_day ymd{days};
return strprintf("%04i-%02u-%02u", signed{ymd.year()}, unsigned{ymd.month()}, unsigned{ymd.day()});
}
std::optional<int64_t> ParseISO8601DateTime(std::string_view str)
{
constexpr auto FMT_SIZE{std::string_view{"2000-01-01T01:01:01Z"}.size()};
if (str.size() != FMT_SIZE || str[4] != '-' || str[7] != '-' || str[10] != 'T' || str[13] != ':' || str[16] != ':' || str[19] != 'Z') {
return {};
}
const auto year{ToIntegral<uint16_t>(str.substr(0, 4))};
const auto month{ToIntegral<uint8_t>(str.substr(5, 2))};
const auto day{ToIntegral<uint8_t>(str.substr(8, 2))};
const auto hour{ToIntegral<uint8_t>(str.substr(11, 2))};
const auto min{ToIntegral<uint8_t>(str.substr(14, 2))};
const auto sec{ToIntegral<uint8_t>(str.substr(17, 2))};
if (!year || !month || !day || !hour || !min || !sec) {
return {};
}
const std::chrono::year_month_day ymd{std::chrono::year{*year}, std::chrono::month{*month}, std::chrono::day{*day}};
if (!ymd.ok()) {
return {};
}
const auto time{std::chrono::hours{*hour} + std::chrono::minutes{*min} + std::chrono::seconds{*sec}};
const auto tp{std::chrono::sys_days{ymd} + time};
return int64_t{TicksSinceEpoch<std::chrono::seconds>(tp)};
}
struct timeval MillisToTimeval(int64_t nTimeout)
{
struct timeval timeout;
timeout.tv_sec = nTimeout / 1000;
timeout.tv_usec = (nTimeout % 1000) * 1000;
return timeout;
}
struct timeval MillisToTimeval(std::chrono::milliseconds ms)
{
return MillisToTimeval(count_milliseconds(ms));
}