Replace non-threadsafe gmtime and setlocale

Make DateTimeStrFormat use boost::posix_time.

Also re-enable the util_DateTimeStrFormat tests, as they are no
longer platform specific.
This commit is contained in:
Wladimir J. van der Laan 2014-05-08 18:01:10 +02:00
parent a60838d09a
commit 3e8ac6af9a
No known key found for this signature in database
GPG Key ID: 74810B012346C9A6
4 changed files with 15 additions and 20 deletions

View File

@ -51,15 +51,7 @@ string HTTPPost(const string& strMsg, const map<string,string>& mapRequestHeader
static string rfc1123Time() static string rfc1123Time()
{ {
char buffer[64]; return DateTimeStrFormat("%a, %d %b %Y %H:%M:%S +0000", GetTime());
time_t now;
time(&now);
struct tm* now_gmt = gmtime(&now);
string locale(setlocale(LC_TIME, NULL));
setlocale(LC_TIME, "C"); // we want POSIX (aka "C") weekday/month strings
strftime(buffer, sizeof(buffer), "%a, %d %b %Y %H:%M:%S +0000", now_gmt);
setlocale(LC_TIME, locale.c_str());
return string(buffer);
} }
string HTTPReply(int nStatus, const string& strMsg, bool keepalive) string HTTPReply(int nStatus, const string& strMsg, bool keepalive)

View File

@ -108,13 +108,11 @@ BOOST_AUTO_TEST_CASE(util_HexStr)
BOOST_AUTO_TEST_CASE(util_DateTimeStrFormat) BOOST_AUTO_TEST_CASE(util_DateTimeStrFormat)
{ {
/*These are platform-dependant and thus removed to avoid useless test failures
BOOST_CHECK_EQUAL(DateTimeStrFormat("%Y-%m-%d %H:%M:%S", 0), "1970-01-01 00:00:00"); BOOST_CHECK_EQUAL(DateTimeStrFormat("%Y-%m-%d %H:%M:%S", 0), "1970-01-01 00:00:00");
BOOST_CHECK_EQUAL(DateTimeStrFormat("%Y-%m-%d %H:%M:%S", 0x7FFFFFFF), "2038-01-19 03:14:07"); BOOST_CHECK_EQUAL(DateTimeStrFormat("%Y-%m-%d %H:%M:%S", 0x7FFFFFFF), "2038-01-19 03:14:07");
// Formats used within Bitcoin
BOOST_CHECK_EQUAL(DateTimeStrFormat("%Y-%m-%d %H:%M:%S", 1317425777), "2011-09-30 23:36:17"); BOOST_CHECK_EQUAL(DateTimeStrFormat("%Y-%m-%d %H:%M:%S", 1317425777), "2011-09-30 23:36:17");
BOOST_CHECK_EQUAL(DateTimeStrFormat("%Y-%m-%d %H:%M", 1317425777), "2011-09-30 23:36"); BOOST_CHECK_EQUAL(DateTimeStrFormat("%Y-%m-%d %H:%M", 1317425777), "2011-09-30 23:36");
*/ BOOST_CHECK_EQUAL(DateTimeStrFormat("%a, %d %b %Y %H:%M:%S +0000", 1317425777), "Fri, 30 Sep 2011 23:36:17 +0000");
} }
BOOST_AUTO_TEST_CASE(util_ParseParameters) BOOST_AUTO_TEST_CASE(util_ParseParameters)

View File

@ -14,6 +14,8 @@
#include <stdarg.h> #include <stdarg.h>
#include <boost/date_time/posix_time/posix_time.hpp>
#ifndef WIN32 #ifndef WIN32
// for posix_fallocate // for posix_fallocate
#ifdef __linux_ #ifdef __linux_
@ -1400,3 +1402,13 @@ void SetupEnvironment()
} }
#endif #endif
} }
std::string DateTimeStrFormat(const char* pszFormat, int64_t nTime)
{
// std::locale takes ownership of the pointer
std::locale loc(std::locale::classic(), new boost::posix_time::time_facet(pszFormat));
std::stringstream ss;
ss.imbue(loc);
ss << boost::posix_time::from_time_t(nTime);
return ss.str();
}

View File

@ -325,14 +325,7 @@ inline int64_t GetTimeMicros()
boost::posix_time::ptime(boost::gregorian::date(1970,1,1))).total_microseconds(); boost::posix_time::ptime(boost::gregorian::date(1970,1,1))).total_microseconds();
} }
inline std::string DateTimeStrFormat(const char* pszFormat, int64_t nTime) std::string DateTimeStrFormat(const char* pszFormat, int64_t nTime);
{
time_t n = nTime;
struct tm* ptmTime = gmtime(&n);
char pszTime[200];
strftime(pszTime, sizeof(pszTime), pszFormat, ptmTime);
return pszTime;
}
inline bool IsSwitchChar(char c) inline bool IsSwitchChar(char c)
{ {