Line data Source code
1 : // Copyright (c) 2009-2010 Satoshi Nakamoto 2 : // Copyright (c) 2009-2020 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 <ctime> 15 : #include <thread> 16 : 17 : #include <tinyformat.h> 18 : 19 64451 : void UninterruptibleSleep(const std::chrono::microseconds& n) { std::this_thread::sleep_for(n); } 20 : 21 : static std::atomic<int64_t> nMockTime(0); //!< For unit testing 22 : 23 2367897 : int64_t GetTime() 24 : { 25 2367897 : int64_t mocktime = nMockTime.load(std::memory_order_relaxed); 26 2367897 : if (mocktime) return mocktime; 27 : 28 1964186 : time_t now = time(nullptr); 29 1964186 : assert(now > 0); 30 : return now; 31 2367899 : } 32 : 33 : template <typename T> 34 1220812 : T GetTime() 35 : { 36 1220812 : const std::chrono::seconds mocktime{nMockTime.load(std::memory_order_relaxed)}; 37 : 38 1220816 : return std::chrono::duration_cast<T>( 39 1220812 : mocktime.count() ? 40 106594 : mocktime : 41 2228436 : std::chrono::microseconds{GetTimeMicros()}); 42 1220816 : } 43 : template std::chrono::seconds GetTime(); 44 : template std::chrono::milliseconds GetTime(); 45 : template std::chrono::microseconds GetTime(); 46 : 47 1989 : void SetMockTime(int64_t nMockTimeIn) 48 : { 49 1989 : nMockTime.store(nMockTimeIn, std::memory_order_relaxed); 50 1989 : } 51 : 52 2155370 : int64_t GetMockTime() 53 : { 54 2155370 : return nMockTime.load(std::memory_order_relaxed); 55 : } 56 : 57 13243 : int64_t GetTimeMillis() 58 : { 59 13243 : int64_t now = (boost::posix_time::microsec_clock::universal_time() - 60 26486 : boost::posix_time::ptime(boost::gregorian::date(1970,1,1))).total_milliseconds(); 61 13243 : assert(now > 0); 62 13243 : return now; 63 : } 64 : 65 5755706 : int64_t GetTimeMicros() 66 : { 67 5755706 : int64_t now = (boost::posix_time::microsec_clock::universal_time() - 68 11511412 : boost::posix_time::ptime(boost::gregorian::date(1970,1,1))).total_microseconds(); 69 5755706 : assert(now > 0); 70 5755601 : return now; 71 : } 72 : 73 684168 : int64_t GetSystemTimeInSeconds() 74 : { 75 684168 : return GetTimeMicros()/1000000; 76 : } 77 : 78 2334509 : std::string FormatISO8601DateTime(int64_t nTime) { 79 2334509 : struct tm ts; 80 2334509 : time_t time_val = nTime; 81 : #ifdef HAVE_GMTIME_R 82 2334509 : if (gmtime_r(&time_val, &ts) == nullptr) { 83 : #else 84 : if (gmtime_s(&ts, &time_val) != 0) { 85 : #endif 86 0 : return {}; 87 : } 88 2334510 : 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); 89 2334510 : } 90 : 91 1002 : std::string FormatISO8601Date(int64_t nTime) { 92 1002 : struct tm ts; 93 1002 : time_t time_val = nTime; 94 : #ifdef HAVE_GMTIME_R 95 1002 : if (gmtime_r(&time_val, &ts) == nullptr) { 96 : #else 97 : if (gmtime_s(&ts, &time_val) != 0) { 98 : #endif 99 0 : return {}; 100 : } 101 1002 : return strprintf("%04i-%02i-%02i", ts.tm_year + 1900, ts.tm_mon + 1, ts.tm_mday); 102 1002 : } 103 : 104 1725 : int64_t ParseISO8601DateTime(const std::string& str) 105 : { 106 1725 : static const boost::posix_time::ptime epoch = boost::posix_time::from_time_t(0); 107 1732 : static const std::locale loc(std::locale::classic(), 108 7 : new boost::posix_time::time_input_facet("%Y-%m-%dT%H:%M:%SZ")); 109 1725 : std::istringstream iss(str); 110 1725 : iss.imbue(loc); 111 1725 : boost::posix_time::ptime ptime(boost::date_time::not_a_date_time); 112 1725 : iss >> ptime; 113 1725 : if (ptime.is_not_a_date_time() || epoch > ptime) 114 861 : return 0; 115 864 : return (ptime - epoch).total_seconds(); 116 1725 : }