Add platform-specific 'z' formatter
This commit is contained in:
parent
be3a3a5aed
commit
5abe9e8266
@ -13,6 +13,7 @@
|
||||
#include <ctime>
|
||||
#include <locale>
|
||||
#include <sstream>
|
||||
#include <type_traits>
|
||||
|
||||
#include "format.h"
|
||||
|
||||
@ -871,6 +872,22 @@ inline const char* tm_mon_short_name(int mon) {
|
||||
return mon >= 0 && mon <= 11 ? short_name_list[mon] : "???";
|
||||
}
|
||||
|
||||
template <typename T, typename = void>
|
||||
struct has_member_data_tm_gmtoff : std::false_type {};
|
||||
template <typename T>
|
||||
struct has_member_data_tm_gmtoff<T, void_t<decltype(T::tm_gmtoff)>>
|
||||
: std::true_type {};
|
||||
|
||||
#if defined(_WIN32)
|
||||
inline void tzset_once() {
|
||||
static bool init = []() -> bool {
|
||||
_tzset();
|
||||
return true;
|
||||
}();
|
||||
ignore_unused(init);
|
||||
}
|
||||
#endif
|
||||
|
||||
template <typename OutputIt, typename Char> class tm_writer {
|
||||
private:
|
||||
static constexpr int days_per_week = 7;
|
||||
@ -988,6 +1005,36 @@ template <typename OutputIt, typename Char> class tm_writer {
|
||||
}
|
||||
}
|
||||
|
||||
void write_utc_offset(long offset) {
|
||||
if (offset < 0) {
|
||||
*out_++ = '-';
|
||||
offset = -offset;
|
||||
} else {
|
||||
*out_++ = '+';
|
||||
}
|
||||
offset /= 60;
|
||||
write2(static_cast<int>(offset / 60));
|
||||
write2(static_cast<int>(offset % 60));
|
||||
}
|
||||
void format_utc_offset_impl(std::true_type) {
|
||||
write_utc_offset(tm_.tm_gmtoff);
|
||||
}
|
||||
void format_utc_offset_impl(std::false_type) {
|
||||
#if defined(_WIN32)
|
||||
tzset_once();
|
||||
long offset = 0;
|
||||
_get_timezone(&offset);
|
||||
if (tm_.tm_isdst) {
|
||||
long dstbias = 0;
|
||||
_get_dstbias(&dstbias);
|
||||
offset += dstbias;
|
||||
}
|
||||
write_utc_offset(-offset);
|
||||
#else
|
||||
format_localized('z');
|
||||
#endif
|
||||
}
|
||||
|
||||
void format_localized(char format, char modifier = 0) {
|
||||
out_ = write<Char>(out_, tm_, loc_, format, modifier);
|
||||
}
|
||||
@ -1094,7 +1141,9 @@ template <typename OutputIt, typename Char> class tm_writer {
|
||||
out_ = copy_str<Char>(std::begin(buf) + offset, std::end(buf), out_);
|
||||
}
|
||||
|
||||
void on_utc_offset() { format_localized('z'); }
|
||||
void on_utc_offset() {
|
||||
format_utc_offset_impl(has_member_data_tm_gmtoff<std::tm>{});
|
||||
}
|
||||
void on_tz_name() { format_localized('Z'); }
|
||||
|
||||
void on_year(numeric_system ns) {
|
||||
|
@ -49,7 +49,14 @@ std::string system_strftime(const std::string& format, const std::tm* timeptr,
|
||||
os.imbue(loc);
|
||||
facet.put(os, os, ' ', timeptr, format.c_str(),
|
||||
format.c_str() + format.size());
|
||||
#ifdef _WIN32
|
||||
// Workaround a bug in older versions of Universal CRT.
|
||||
auto str = os.str();
|
||||
if (str == "-0000") str = "+0000";
|
||||
return str;
|
||||
#else
|
||||
return os.str();
|
||||
#endif
|
||||
}
|
||||
|
||||
FMT_CONSTEXPR std::tm make_tm(int year, int mon, int mday, int hour, int min,
|
||||
|
@ -277,7 +277,14 @@ std::wstring system_wcsftime(const std::wstring& format, const std::tm* timeptr,
|
||||
os.imbue(loc);
|
||||
facet.put(os, os, L' ', timeptr, format.c_str(),
|
||||
format.c_str() + format.size());
|
||||
#ifdef _WIN32
|
||||
// Workaround a bug in older versions of Universal CRT.
|
||||
auto str = os.str();
|
||||
if (str == L"-0000") str = L"+0000";
|
||||
return str;
|
||||
#else
|
||||
return os.str();
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(chrono_test, time_point) {
|
||||
|
Loading…
Reference in New Issue
Block a user