1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2018 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 #if defined(HAVE_CONFIG_H)
7 #include <config/bitcoin-config.h>
8 #endif
9
10 #include <util/time.h>
11
12 #include <atomic>
13 #include <boost/date_time/posix_time/posix_time.hpp>
14 #include <boost/thread.hpp>
15 #include <ctime>
16 #include <tinyformat.h>
17
18 static std::atomic<int64_t> nMockTime(0); //!< For unit testing
19
GetTime()20 int64_t GetTime()
21 {
22 int64_t mocktime = nMockTime.load(std::memory_order_relaxed);
23 if (mocktime) return mocktime;
24
25 time_t now = time(nullptr);
26 assert(now > 0);
27 return now;
28 }
29
SetMockTime(int64_t nMockTimeIn)30 void SetMockTime(int64_t nMockTimeIn)
31 {
32 nMockTime.store(nMockTimeIn, std::memory_order_relaxed);
33 }
34
GetMockTime()35 int64_t GetMockTime()
36 {
37 return nMockTime.load(std::memory_order_relaxed);
38 }
39
GetTimeMillis()40 int64_t GetTimeMillis()
41 {
42 int64_t now = (boost::posix_time::microsec_clock::universal_time() -
43 boost::posix_time::ptime(boost::gregorian::date(1970,1,1))).total_milliseconds();
44 assert(now > 0);
45 return now;
46 }
47
GetTimeMicros()48 int64_t GetTimeMicros()
49 {
50 int64_t now = (boost::posix_time::microsec_clock::universal_time() -
51 boost::posix_time::ptime(boost::gregorian::date(1970,1,1))).total_microseconds();
52 assert(now > 0);
53 return now;
54 }
55
GetSystemTimeInSeconds()56 int64_t GetSystemTimeInSeconds()
57 {
58 return GetTimeMicros()/1000000;
59 }
60
MilliSleep(int64_t n)61 void MilliSleep(int64_t n)
62 {
63
64 /**
65 * Boost's sleep_for was uninterruptible when backed by nanosleep from 1.50
66 * until fixed in 1.52. Use the deprecated sleep method for the broken case.
67 * See: https://svn.boost.org/trac/boost/ticket/7238
68 */
69 #if defined(HAVE_WORKING_BOOST_SLEEP_FOR)
70 boost::this_thread::sleep_for(boost::chrono::milliseconds(n));
71 #elif defined(HAVE_WORKING_BOOST_SLEEP)
72 boost::this_thread::sleep(boost::posix_time::milliseconds(n));
73 #else
74 //should never get here
75 #error missing boost sleep implementation
76 #endif
77 }
78
FormatISO8601DateTime(int64_t nTime)79 std::string FormatISO8601DateTime(int64_t nTime) {
80 struct tm ts;
81 time_t time_val = nTime;
82 #ifdef _MSC_VER
83 gmtime_s(&ts, &time_val);
84 #else
85 gmtime_r(&time_val, &ts);
86 #endif
87 return strprintf("%04i-%02i-%02iT%02i:%02i:%02iZ", ts.tm_year + 1900, ts.tm_mon + 1, ts.tm_mday, ts.tm_hour, ts.tm_min, ts.tm_sec);
88 }
89
FormatISO8601Date(int64_t nTime)90 std::string FormatISO8601Date(int64_t nTime) {
91 struct tm ts;
92 time_t time_val = nTime;
93 #ifdef _MSC_VER
94 gmtime_s(&ts, &time_val);
95 #else
96 gmtime_r(&time_val, &ts);
97 #endif
98 return strprintf("%04i-%02i-%02i", ts.tm_year + 1900, ts.tm_mon + 1, ts.tm_mday);
99 }
100
FormatISO8601Time(int64_t nTime)101 std::string FormatISO8601Time(int64_t nTime) {
102 struct tm ts;
103 time_t time_val = nTime;
104 #ifdef _MSC_VER
105 gmtime_s(&ts, &time_val);
106 #else
107 gmtime_r(&time_val, &ts);
108 #endif
109 return strprintf("%02i:%02i:%02iZ", ts.tm_hour, ts.tm_min, ts.tm_sec);
110 }
111