mirror of
https://github.com/fmtlib/fmt.git
synced 2025-07-29 18:27:40 +02:00
Test timezone
This commit is contained in:
@ -1268,28 +1268,8 @@ class tm_writer {
|
||||
write_utc_offset(tm.tm_gmtoff, ns);
|
||||
}
|
||||
template <typename T, FMT_ENABLE_IF(!has_member_data_tm_gmtoff<T>::value)>
|
||||
void format_utc_offset_impl(const T& tm, numeric_system ns) {
|
||||
#if defined(_WIN32) && defined(_UCRT)
|
||||
tzset_once();
|
||||
long offset = 0;
|
||||
_get_timezone(&offset);
|
||||
if (tm.tm_isdst) {
|
||||
long dstbias = 0;
|
||||
_get_dstbias(&dstbias);
|
||||
offset += dstbias;
|
||||
}
|
||||
write_utc_offset(-offset, ns);
|
||||
#else
|
||||
if (ns == numeric_system::standard) return format_localized('z');
|
||||
|
||||
// Extract timezone offset from timezone conversion functions.
|
||||
std::tm gtm = tm;
|
||||
std::time_t gt = std::mktime(>m);
|
||||
std::tm ltm = gmtime(gt);
|
||||
std::time_t lt = std::mktime(<m);
|
||||
long long offset = gt - lt;
|
||||
write_utc_offset(offset, ns);
|
||||
#endif
|
||||
void format_utc_offset_impl(const T&, numeric_system ns) {
|
||||
write_utc_offset(0, ns);
|
||||
}
|
||||
|
||||
template <typename T, FMT_ENABLE_IF(has_member_data_tm_zone<T>::value)>
|
||||
|
@ -263,7 +263,11 @@ auto strftime_full_utc(TimePoint tp) -> std::string {
|
||||
return system_strftime("%Y-%m-%d %H:%M:%S", &tm);
|
||||
}
|
||||
|
||||
TEST(chrono_test, system_clock_time_point) {
|
||||
TEST(chrono_test, sys_time) {
|
||||
auto time =
|
||||
fmt::sys_time<std::chrono::seconds>(std::chrono::seconds(290088000));
|
||||
EXPECT_EQ(fmt::format("{:%z}", time), "+0000");
|
||||
|
||||
auto t1 = std::chrono::time_point_cast<std::chrono::seconds>(
|
||||
std::chrono::system_clock::now());
|
||||
EXPECT_EQ(strftime_full_utc(t1), fmt::format("{:%Y-%m-%d %H:%M:%S}", t1));
|
||||
@ -303,7 +307,7 @@ TEST(chrono_test, system_clock_time_point) {
|
||||
}
|
||||
|
||||
// Timezone formatters tests makes sense for localtime.
|
||||
#if FMT_HAS_C99_STRFTIME
|
||||
#if FMT_HAS_C99_STRFTIME && !defined(_WIN32)
|
||||
spec_list = {"%z", "%Z"};
|
||||
#else
|
||||
spec_list = {"%Z"};
|
||||
|
@ -224,106 +224,9 @@ TEST(xchar_test, chrono) {
|
||||
EXPECT_EQ(L"42s", fmt::format(L"{}", std::chrono::seconds(42)));
|
||||
EXPECT_EQ(fmt::format(L"{:%F}", tm), L"2016-04-25");
|
||||
EXPECT_EQ(fmt::format(L"{:%T}", tm), L"11:22:33");
|
||||
}
|
||||
|
||||
std::wstring system_wcsftime(const std::wstring& format, const std::tm* timeptr,
|
||||
std::locale* locptr = nullptr) {
|
||||
auto loc = locptr ? *locptr : std::locale::classic();
|
||||
auto& facet = std::use_facet<std::time_put<wchar_t>>(loc);
|
||||
std::wostringstream os;
|
||||
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_wchar, time_point) {
|
||||
auto t1 = std::chrono::time_point_cast<std::chrono::seconds>(
|
||||
std::chrono::system_clock::now());
|
||||
|
||||
std::vector<std::wstring> spec_list = {
|
||||
L"%%", L"%n", L"%t", L"%Y", L"%EY", L"%y", L"%Oy", L"%Ey", L"%C",
|
||||
L"%EC", L"%G", L"%g", L"%b", L"%h", L"%B", L"%m", L"%Om", L"%U",
|
||||
L"%OU", L"%W", L"%OW", L"%V", L"%OV", L"%j", L"%d", L"%Od", L"%e",
|
||||
L"%Oe", L"%a", L"%A", L"%w", L"%Ow", L"%u", L"%Ou", L"%H", L"%OH",
|
||||
L"%I", L"%OI", L"%M", L"%OM", L"%S", L"%OS", L"%x", L"%Ex", L"%X",
|
||||
L"%EX", L"%D", L"%F", L"%R", L"%T", L"%p"};
|
||||
#ifndef _WIN32
|
||||
// Disabled on Windows, because these formats is not consistent among
|
||||
// platforms.
|
||||
spec_list.insert(spec_list.end(), {L"%c", L"%Ec", L"%r"});
|
||||
#elif !FMT_HAS_C99_STRFTIME
|
||||
// Only C89 conversion specifiers when using MSVCRT instead of UCRT
|
||||
spec_list = {L"%%", L"%Y", L"%y", L"%b", L"%B", L"%m", L"%U",
|
||||
L"%W", L"%j", L"%d", L"%a", L"%A", L"%w", L"%H",
|
||||
L"%I", L"%M", L"%S", L"%x", L"%X", L"%p"};
|
||||
#endif
|
||||
spec_list.push_back(L"%Y-%m-%d %H:%M:%S");
|
||||
|
||||
for (const auto& spec : spec_list) {
|
||||
auto t = std::chrono::system_clock::to_time_t(t1);
|
||||
auto tm = *std::gmtime(&t);
|
||||
|
||||
auto sys_output = system_wcsftime(spec, &tm);
|
||||
|
||||
auto fmt_spec = fmt::format(L"{{:{}}}", spec);
|
||||
EXPECT_EQ(sys_output, fmt::format(fmt::runtime(fmt_spec), t1));
|
||||
EXPECT_EQ(sys_output, fmt::format(fmt::runtime(fmt_spec), tm));
|
||||
}
|
||||
|
||||
// Timezone formatters tests makes sense for localtime.
|
||||
#if FMT_HAS_C99_STRFTIME
|
||||
spec_list = {L"%z", L"%Z"};
|
||||
#else
|
||||
spec_list = {L"%Z"};
|
||||
#endif
|
||||
for (const auto& spec : spec_list) {
|
||||
auto t = std::chrono::system_clock::to_time_t(t1);
|
||||
auto tm = *std::localtime(&t);
|
||||
|
||||
auto sys_output = system_wcsftime(spec, &tm);
|
||||
|
||||
auto fmt_spec = fmt::format(L"{{:{}}}", spec);
|
||||
EXPECT_EQ(sys_output, fmt::format(fmt::runtime(fmt_spec), tm));
|
||||
|
||||
if (spec == L"%z") {
|
||||
sys_output.insert(sys_output.end() - 2, 1, L':');
|
||||
EXPECT_EQ(sys_output, fmt::format(L"{:%Ez}", tm));
|
||||
EXPECT_EQ(sys_output, fmt::format(L"{:%Oz}", tm));
|
||||
}
|
||||
}
|
||||
|
||||
// Separate tests for UTC, since std::time_put can use local time and ignoring
|
||||
// the timezone in std::tm (if it presents on platform).
|
||||
if (fmt::detail::has_member_data_tm_zone<std::tm>::value) {
|
||||
auto t = std::chrono::system_clock::to_time_t(t1);
|
||||
auto tm = *std::gmtime(&t);
|
||||
|
||||
std::vector<std::wstring> tz_names = {L"GMT", L"UTC"};
|
||||
EXPECT_THAT(tz_names, Contains(fmt::format(L"{:%Z}", t1)));
|
||||
EXPECT_THAT(tz_names, Contains(fmt::format(L"{:%Z}", tm)));
|
||||
}
|
||||
|
||||
if (fmt::detail::has_member_data_tm_gmtoff<std::tm>::value) {
|
||||
auto t = std::chrono::system_clock::to_time_t(t1);
|
||||
auto tm = *std::gmtime(&t);
|
||||
|
||||
EXPECT_EQ(L"+0000", fmt::format(L"{:%z}", t1));
|
||||
EXPECT_EQ(L"+0000", fmt::format(L"{:%z}", tm));
|
||||
|
||||
EXPECT_EQ(L"+00:00", fmt::format(L"{:%Ez}", t1));
|
||||
EXPECT_EQ(L"+00:00", fmt::format(L"{:%Ez}", tm));
|
||||
|
||||
EXPECT_EQ(L"+00:00", fmt::format(L"{:%Oz}", t1));
|
||||
EXPECT_EQ(L"+00:00", fmt::format(L"{:%Oz}", tm));
|
||||
}
|
||||
auto t = fmt::sys_time<std::chrono::seconds>(std::chrono::seconds(290088000));
|
||||
EXPECT_EQ(fmt::format("{:%Y-%m-%d %H:%M:%S}", t), "1979-03-12 12:00:00");
|
||||
}
|
||||
|
||||
TEST(xchar_test, color) {
|
||||
|
Reference in New Issue
Block a user