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