Add formatters for chrono::time_point and helper overloads for localtime/gmtime(time_point)
Fixes #1819
This commit is contained in:
parent
c7e6d8afb0
commit
75c59ed3ba
@ -351,6 +351,11 @@ inline std::tm localtime(std::time_t time) {
|
|||||||
return lt.tm_;
|
return lt.tm_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline std::tm localtime(
|
||||||
|
std::chrono::time_point<std::chrono::system_clock> time_point) {
|
||||||
|
return localtime(std::chrono::system_clock::to_time_t(time_point));
|
||||||
|
}
|
||||||
|
|
||||||
// Thread-safe replacement for std::gmtime
|
// Thread-safe replacement for std::gmtime
|
||||||
inline std::tm gmtime(std::time_t time) {
|
inline std::tm gmtime(std::time_t time) {
|
||||||
struct dispatcher {
|
struct dispatcher {
|
||||||
@ -387,6 +392,11 @@ inline std::tm gmtime(std::time_t time) {
|
|||||||
return gt.tm_;
|
return gt.tm_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline std::tm gmtime(
|
||||||
|
std::chrono::time_point<std::chrono::system_clock> time_point) {
|
||||||
|
return gmtime(std::chrono::system_clock::to_time_t(time_point));
|
||||||
|
}
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
inline size_t strftime(char* str, size_t count, const char* format,
|
inline size_t strftime(char* str, size_t count, const char* format,
|
||||||
const std::tm* time) {
|
const std::tm* time) {
|
||||||
@ -399,6 +409,17 @@ inline size_t strftime(wchar_t* str, size_t count, const wchar_t* format,
|
|||||||
}
|
}
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
|
template <typename Char>
|
||||||
|
struct formatter<std::chrono::time_point<std::chrono::system_clock>, Char>
|
||||||
|
: formatter<std::tm, Char> {
|
||||||
|
template <typename FormatContext>
|
||||||
|
auto format(std::chrono::time_point<std::chrono::system_clock> val,
|
||||||
|
FormatContext& ctx) -> decltype(ctx.out()) {
|
||||||
|
std::tm time = localtime(val);
|
||||||
|
return formatter<std::tm, Char>::format(time, ctx);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template <typename Char> struct formatter<std::tm, Char> {
|
template <typename Char> struct formatter<std::tm, Char> {
|
||||||
template <typename ParseContext>
|
template <typename ParseContext>
|
||||||
auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
|
auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
|
||||||
|
|||||||
@ -95,6 +95,28 @@ TEST(TimeTest, GMTime) {
|
|||||||
EXPECT_TRUE(EqualTime(tm, fmt::gmtime(t)));
|
EXPECT_TRUE(EqualTime(tm, fmt::gmtime(t)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(TimeTest, TimePoint) {
|
||||||
|
setenv("TZ", "EST+5", 1);
|
||||||
|
tzset();
|
||||||
|
std::chrono::system_clock::time_point point(std::chrono::seconds(1598412345));
|
||||||
|
EXPECT_EQ("It is 2020-08-25 22:25:45.",
|
||||||
|
fmt::format("It is {:%Y-%m-%d %H:%M:%S}.", point));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(TimeTest, LocalTimeWithTimePoint) {
|
||||||
|
setenv("TZ", "EST+5", 1);
|
||||||
|
tzset();
|
||||||
|
std::chrono::system_clock::time_point point(std::chrono::seconds(1598412345));
|
||||||
|
EXPECT_EQ("It is 2020-08-25 22:25:45.",
|
||||||
|
fmt::format("It is {:%Y-%m-%d %H:%M:%S}.", fmt::localtime(point)));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(TimeTest, GMTimeWithTimePoint) {
|
||||||
|
std::chrono::system_clock::time_point point(std::chrono::seconds(1598412345));
|
||||||
|
EXPECT_EQ("It is 2020-08-26 03:25:45 UTC.",
|
||||||
|
fmt::format("It is {:%Y-%m-%d %H:%M:%S} UTC.", fmt::gmtime(point)));
|
||||||
|
}
|
||||||
|
|
||||||
#define EXPECT_TIME(spec, time, duration) \
|
#define EXPECT_TIME(spec, time, duration) \
|
||||||
{ \
|
{ \
|
||||||
std::locale loc("ja_JP.utf8"); \
|
std::locale loc("ja_JP.utf8"); \
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user