Add initial support for weekday formatting

This commit is contained in:
Victor Zverovich
2021-05-24 07:23:56 -07:00
parent 069131dc25
commit 1cd9899cf3
6 changed files with 157 additions and 33 deletions

View File

@@ -8,9 +8,12 @@
#include "fmt/chrono.h"
#include "gtest-extra.h" // EXPECT_THROW_MSG
#include "util.h" // get_locale
using fmt::runtime;
using testing::Contains;
auto make_tm() -> std::tm {
auto time = std::tm();
time.tm_mday = 1;
@@ -246,26 +249,15 @@ auto format_tm(const std::tm& time, fmt::string_view spec,
return os.str();
}
TEST(chrono_test, locale) {
auto loc = get_locale("ja_JP.utf8");
if (loc == std::locale::classic()) return;
# define EXPECT_TIME(spec, time, duration) \
{ \
auto jp_loc = std::locale("ja_JP.utf8"); \
EXPECT_EQ(format_tm(time, spec, jp_loc), \
fmt::format(jp_loc, "{:L" spec "}", duration)); \
}
TEST(chrono_test, locale) {
auto loc_name = "ja_JP.utf8";
bool has_locale = false;
auto loc = std::locale();
try {
loc = std::locale(loc_name);
has_locale = true;
} catch (const std::runtime_error&) {
}
if (!has_locale) {
fmt::print("{} locale is missing.\n", loc_name);
return;
}
EXPECT_TIME("%OH", make_hour(14), std::chrono::hours(14));
EXPECT_TIME("%OI", make_hour(14), std::chrono::hours(14));
EXPECT_TIME("%OM", make_minute(42), std::chrono::minutes(42));
@@ -384,4 +376,14 @@ TEST(chrono_test, unsigned_duration) {
EXPECT_EQ("42s", fmt::format("{}", std::chrono::duration<unsigned>(42)));
}
TEST(chrono_test, format_weekday) {
auto loc = get_locale("ru_RU.UTF-8");
std::locale::global(loc);
EXPECT_EQ(fmt::format("{}", fmt::weekday(1)), "Mon");
if (loc != std::locale::classic()) {
EXPECT_THAT((std::vector<std::string>{"пн", "Пн"}),
Contains(fmt::format(loc, "{:L}", fmt::weekday(1))));
}
}
#endif // FMT_STATIC_THOUSANDS_SEPARATOR

View File

@@ -5,7 +5,25 @@
//
// For the license information refer to format.h.
#include "fmt/core.h"
#include "gtest/gtest.h"
#include <vector>
TEST(unicode_test, is_utf8) { EXPECT_TRUE(fmt::detail::is_utf8()); }
#include "fmt/chrono.h"
#include "gmock/gmock.h"
#include "util.h" // get_locale
using testing::Contains;
TEST(unicode_test, is_utf8) { EXPECT_TRUE(fmt::detail::is_utf8()); }
TEST(unicode_test, legacy_locale) {
auto loc = get_locale("ru_RU.CP1251");
if (loc == std::locale::classic()) return;
try {
EXPECT_THAT(
(std::vector<std::string>{"День недели: пн", "День недели: Пн"}),
Contains(fmt::format(loc, "День недели: {:L}", fmt::weekday(1))));
} catch (const fmt::format_error& e) {
// Formatting can fail due to unsupported encoding.
fmt::print("Format error: {}\n", e.what());
}
}

View File

@@ -26,3 +26,12 @@ fmt::buffered_file open_buffered_file(FILE** fp) {
#endif
return f;
}
std::locale get_locale(const char* name) {
try {
return std::locale(name);
} catch (const std::runtime_error&) {
fmt::print(stderr, "{} locale is missing.\n", name);
}
return std::locale::classic();
}

View File

@@ -7,6 +7,7 @@
#include <cstdarg>
#include <cstdio>
#include <locale>
#include <string>
#include "fmt/os.h"
@@ -75,3 +76,6 @@ class date {
int month() const { return month_; }
int day() const { return day_; }
};
// Returns a locale with the given name if available or classic locale othewise.
std::locale get_locale(const char* name);