Skip to content

Commit dec6115

Browse files
committed
Merge #12973: Avoid std::locale/imbue madness in DateTimeStrFormat
1527015 Avoid std::locale/imbue in DateTimeStrFormat (Pieter Wuille) Pull request description: And replace them with just hardcoded ISO8601 strings and `gmtime_r`. Pointed out by @laanwj here: bitcoin/bitcoin#12970 (comment) Tree-SHA512: a459758b42ca56f8462115aefe8e6377c1319fce509ea64dbb767f3f087c9b848335954cb684e5896c38008847684045505a3e1559fb3e83b8e80e10b003d1e7
2 parents 5f2a399 + 1527015 commit dec6115

File tree

3 files changed

+14
-28
lines changed

3 files changed

+14
-28
lines changed

src/test/util_tests.cpp

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -159,17 +159,6 @@ BOOST_AUTO_TEST_CASE(util_HexStr)
159159
}
160160

161161

162-
BOOST_AUTO_TEST_CASE(util_DateTimeStrFormat)
163-
{
164-
BOOST_CHECK_EQUAL(DateTimeStrFormat("%Y-%m-%d %H:%M:%S", 0), "1970-01-01 00:00:00");
165-
BOOST_CHECK_EQUAL(DateTimeStrFormat("%Y-%m-%d %H:%M:%S", 0x7FFFFFFF), "2038-01-19 03:14:07");
166-
BOOST_CHECK_EQUAL(DateTimeStrFormat("%Y-%m-%d %H:%M:%S", 1317425777), "2011-09-30 23:36:17");
167-
BOOST_CHECK_EQUAL(DateTimeStrFormat("%Y-%m-%dT%H:%M:%SZ", 1317425777), "2011-09-30T23:36:17Z");
168-
BOOST_CHECK_EQUAL(DateTimeStrFormat("%H:%M:%SZ", 1317425777), "23:36:17Z");
169-
BOOST_CHECK_EQUAL(DateTimeStrFormat("%Y-%m-%d %H:%M", 1317425777), "2011-09-30 23:36");
170-
BOOST_CHECK_EQUAL(DateTimeStrFormat("%a, %d %b %Y %H:%M:%S +0000", 1317425777), "Fri, 30 Sep 2011 23:36:17 +0000");
171-
}
172-
173162
BOOST_AUTO_TEST_CASE(util_FormatISO8601DateTime)
174163
{
175164
BOOST_CHECK_EQUAL(FormatISO8601DateTime(1317425777), "2011-09-30T23:36:17Z");

src/utiltime.cpp

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,10 @@
1010
#include <utiltime.h>
1111

1212
#include <atomic>
13-
1413
#include <boost/date_time/posix_time/posix_time.hpp>
1514
#include <boost/thread.hpp>
15+
#include <ctime>
16+
#include <tinyformat.h>
1617

1718
static std::atomic<int64_t> nMockTime(0); //!< For unit testing
1819

@@ -75,25 +76,23 @@ void MilliSleep(int64_t n)
7576
#endif
7677
}
7778

78-
std::string DateTimeStrFormat(const char* pszFormat, int64_t nTime)
79-
{
80-
static std::locale classic(std::locale::classic());
81-
// std::locale takes ownership of the pointer
82-
std::locale loc(classic, new boost::posix_time::time_facet(pszFormat));
83-
std::stringstream ss;
84-
ss.imbue(loc);
85-
ss << boost::posix_time::from_time_t(nTime);
86-
return ss.str();
87-
}
88-
8979
std::string FormatISO8601DateTime(int64_t nTime) {
90-
return DateTimeStrFormat("%Y-%m-%dT%H:%M:%SZ", nTime);
80+
struct tm ts;
81+
time_t time_val = nTime;
82+
gmtime_r(&time_val, &ts);
83+
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);
9184
}
9285

9386
std::string FormatISO8601Date(int64_t nTime) {
94-
return DateTimeStrFormat("%Y-%m-%d", nTime);
87+
struct tm ts;
88+
time_t time_val = nTime;
89+
gmtime_r(&time_val, &ts);
90+
return strprintf("%04i-%02i-%02i", ts.tm_year + 1900, ts.tm_mon + 1, ts.tm_mday);
9591
}
9692

9793
std::string FormatISO8601Time(int64_t nTime) {
98-
return DateTimeStrFormat("%H:%M:%SZ", nTime);
94+
struct tm ts;
95+
time_t time_val = nTime;
96+
gmtime_r(&time_val, &ts);
97+
return strprintf("%02i:%02i:%02iZ", ts.tm_hour, ts.tm_min, ts.tm_sec);
9998
}

src/utiltime.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,6 @@ void MilliSleep(int64_t n);
3131
* ISO 8601 formatting is preferred. Use the FormatISO8601{DateTime,Date,Time}
3232
* helper functions if possible.
3333
*/
34-
std::string DateTimeStrFormat(const char* pszFormat, int64_t nTime);
35-
3634
std::string FormatISO8601DateTime(int64_t nTime);
3735
std::string FormatISO8601Date(int64_t nTime);
3836
std::string FormatISO8601Time(int64_t nTime);

0 commit comments

Comments
 (0)