diff --git a/include/fmt/chrono.h b/include/fmt/chrono.h index a366ea6b887d4..ff785139bbf1c 100644 --- a/include/fmt/chrono.h +++ b/include/fmt/chrono.h @@ -988,6 +988,18 @@ template class tm_writer { } } + void write_utc_offset(long offset) { + if (offset < 0) { + *out_++ = '-'; + offset = -offset; + } else { + *out_++ = '+'; + } + offset /= 60; + write2(static_cast(offset / 60)); + write2(static_cast(offset % 60)); + } + void format_localized(char format, char modifier = 0) { out_ = write(out_, tm_, loc_, format, modifier); } @@ -1093,7 +1105,29 @@ template class tm_writer { out_ = copy_str(std::begin(buf) + offset, std::end(buf), out_); } - void on_utc_offset() { format_localized('z'); } + void on_utc_offset() { +#if defined(_WIN32) + _tzset(); + long offset = 0; + _get_timezone(&offset); + if (tm_.tm_isdst) { + long dstbias = 0; + _get_dstbias(&dstbias); + offset += dstbias; + } + write_utc_offset(-offset); +#elif defined(__APPLE__) || defined(__GLIBC__) || defined(__FreeBSD__) || \ + defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) + write_utc_offset(tm_.tm_gmtoff); +#elif defined(sun) || defined(__sun) + tzset(); + write_utc_offset( + static_cast(tm_.tm_isdst == 0 ? -timezone : -altzone)); +#else + // For exotic platforms. + format_localized('z'); +#endif + } void on_tz_name() { format_localized('Z'); } void on_year(numeric_system ns) { diff --git a/test/chrono-test.cc b/test/chrono-test.cc index fc773c531c752..d72838560992b 100644 --- a/test/chrono-test.cc +++ b/test/chrono-test.cc @@ -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 to early ucrt bug + 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, diff --git a/test/xchar-test.cc b/test/xchar-test.cc index 8f98c05048828..adba08e9cbb53 100644 --- a/test/xchar-test.cc +++ b/test/xchar-test.cc @@ -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 to early ucrt bug + auto str = os.str(); + if (str == L"-0000") str = L"+0000"; + return str; +#else return os.str(); +#endif } TEST(chrono_test, time_point) {