Add platform-specific 'z' formatter
This commit is contained in:
parent
be3a3a5aed
commit
5abe9e8266
@ -13,6 +13,7 @@
|
|||||||
#include <ctime>
|
#include <ctime>
|
||||||
#include <locale>
|
#include <locale>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
#include "format.h"
|
#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] : "???";
|
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 {
|
template <typename OutputIt, typename Char> class tm_writer {
|
||||||
private:
|
private:
|
||||||
static constexpr int days_per_week = 7;
|
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) {
|
void format_localized(char format, char modifier = 0) {
|
||||||
out_ = write<Char>(out_, tm_, loc_, format, modifier);
|
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_);
|
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_tz_name() { format_localized('Z'); }
|
||||||
|
|
||||||
void on_year(numeric_system ns) {
|
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);
|
os.imbue(loc);
|
||||||
facet.put(os, os, ' ', timeptr, format.c_str(),
|
facet.put(os, os, ' ', timeptr, format.c_str(),
|
||||||
format.c_str() + format.size());
|
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();
|
return os.str();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
FMT_CONSTEXPR std::tm make_tm(int year, int mon, int mday, int hour, int min,
|
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);
|
os.imbue(loc);
|
||||||
facet.put(os, os, L' ', timeptr, format.c_str(),
|
facet.put(os, os, L' ', timeptr, format.c_str(),
|
||||||
format.c_str() + format.size());
|
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();
|
return os.str();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(chrono_test, time_point) {
|
TEST(chrono_test, time_point) {
|
||||||
|
Loading…
Reference in New Issue
Block a user