aboutsummaryrefslogtreecommitdiff
path: root/src/util/time.cpp
diff options
context:
space:
mode:
authorWladimir J. van der Laan <laanwj@protonmail.com>2021-02-17 20:23:25 +0100
committerWladimir J. van der Laan <laanwj@protonmail.com>2021-02-17 20:38:08 +0100
commit372dd8da2475d7df584d31fa03f0b4d703b7c8f5 (patch)
tree6a10a112840bca2020037e621993b586a1609f55 /src/util/time.cpp
parent04336086d3cb2a738e82cf54d9995474ca485f0c (diff)
parent9266f7497f256d780178829e0f3a29ddaeb794ba (diff)
downloadbitcoin-372dd8da2475d7df584d31fa03f0b4d703b7c8f5.tar.xz
Merge #21110: util: remove Boost posix_time usage from GetTime*
9266f7497f256d780178829e0f3a29ddaeb794ba util: Use std::chrono for time getters (MarcoFalke) 3c2e16be22ae04bf56663ee5ec1554d0d569741b time: add runtime sanity check (Cory Fields) Pull request description: I have a followup that should remove the last of our `boost:posix_time` usage in `ParseISO8601DateTime`, but that will likely need more cross-platform testing/discussion, so have just split them up as this change is straight forward. ACKs for top commit: practicalswift: Tested ACK 9266f7497f256d780178829e0f3a29ddaeb794ba laanwj: Code review ACK 9266f7497f256d780178829e0f3a29ddaeb794ba Tree-SHA512: 5471a60e65e9fa8ef48320743ef637f1d162724e717e0f5509118e1e5732fc0844656a9c09d3d1300eb657dcc7a1e1e67305d8c9ef959c63be67393607dd4ceb
Diffstat (limited to 'src/util/time.cpp')
-rw-r--r--src/util/time.cpp63
1 files changed, 54 insertions, 9 deletions
diff --git a/src/util/time.cpp b/src/util/time.cpp
index 7b0eb8fd8e..e6f0986a39 100644
--- a/src/util/time.cpp
+++ b/src/util/time.cpp
@@ -33,6 +33,49 @@ int64_t GetTime()
return now;
}
+bool ChronoSanityCheck()
+{
+ // std::chrono::system_clock.time_since_epoch and time_t(0) are not guaranteed
+ // to use the Unix epoch timestamp, prior to C++20, but in practice they almost
+ // certainly will. Any differing behavior will be assumed to be an error, unless
+ // certain platforms prove to consistently deviate, at which point we'll cope
+ // with it by adding offsets.
+
+ // Create a new clock from time_t(0) and make sure that it represents 0
+ // seconds from the system_clock's time_since_epoch. Then convert that back
+ // to a time_t and verify that it's the same as before.
+ const time_t time_t_epoch{};
+ auto clock = std::chrono::system_clock::from_time_t(time_t_epoch);
+ if (std::chrono::duration_cast<std::chrono::seconds>(clock.time_since_epoch()).count() != 0) {
+ return false;
+ }
+
+ time_t time_val = std::chrono::system_clock::to_time_t(clock);
+ if (time_val != time_t_epoch) {
+ return false;
+ }
+
+ // Check that the above zero time is actually equal to the known unix timestamp.
+ struct tm epoch;
+#ifdef HAVE_GMTIME_R
+ if (gmtime_r(&time_val, &epoch) == nullptr) {
+#else
+ if (gmtime_s(&epoch, &time_val) != 0) {
+#endif
+ return false;
+ }
+
+ if ((epoch.tm_sec != 0) ||
+ (epoch.tm_min != 0) ||
+ (epoch.tm_hour != 0) ||
+ (epoch.tm_mday != 1) ||
+ (epoch.tm_mon != 0) ||
+ (epoch.tm_year != 70)) {
+ return false;
+ }
+ return true;
+}
+
template <typename T>
T GetTime()
{
@@ -47,6 +90,14 @@ template std::chrono::seconds GetTime();
template std::chrono::milliseconds GetTime();
template std::chrono::microseconds GetTime();
+template <typename T>
+static T GetSystemTime()
+{
+ const auto now = std::chrono::duration_cast<T>(std::chrono::system_clock::now().time_since_epoch());
+ assert(now.count() > 0);
+ return now;
+}
+
void SetMockTime(int64_t nMockTimeIn)
{
Assert(nMockTimeIn >= 0);
@@ -65,23 +116,17 @@ std::chrono::seconds GetMockTime()
int64_t GetTimeMillis()
{
- int64_t now = (boost::posix_time::microsec_clock::universal_time() -
- boost::posix_time::ptime(boost::gregorian::date(1970,1,1))).total_milliseconds();
- assert(now > 0);
- return now;
+ return int64_t{GetSystemTime<std::chrono::milliseconds>().count()};
}
int64_t GetTimeMicros()
{
- int64_t now = (boost::posix_time::microsec_clock::universal_time() -
- boost::posix_time::ptime(boost::gregorian::date(1970,1,1))).total_microseconds();
- assert(now > 0);
- return now;
+ return int64_t{GetSystemTime<std::chrono::microseconds>().count()};
}
int64_t GetSystemTimeInSeconds()
{
- return GetTimeMicros()/1000000;
+ return int64_t{GetSystemTime<std::chrono::seconds>().count()};
}
std::string FormatISO8601DateTime(int64_t nTime) {