Skip to content

Commit

Permalink
Add platform-specific 'z' formatter
Browse files Browse the repository at this point in the history
  • Loading branch information
phprus committed Nov 14, 2021
1 parent 8dc1153 commit 76da43b
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 1 deletion.
36 changes: 35 additions & 1 deletion include/fmt/chrono.h
Original file line number Diff line number Diff line change
Expand Up @@ -988,6 +988,18 @@ 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_localized(char format, char modifier = 0) {
out_ = write<Char>(out_, tm_, loc_, format, modifier);
}
Expand Down Expand Up @@ -1093,7 +1105,29 @@ 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() {
#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<long>(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) {
Expand Down
7 changes: 7 additions & 0 deletions test/chrono-test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
7 changes: 7 additions & 0 deletions test/xchar-test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down

0 comments on commit 76da43b

Please sign in to comment.