使用包含日期、时间和亚秒的格式使用 std::format 将 time_point 转换为字符串
Convert time_point to string using std::format with format that includes date, time and subseconds
假设我们有一个简单的函数,它使用给定的格式字符串获取 std::chrono::time_point 和 returns 字符串。像这样:
std::string DateTimeToString(std::chrono::sys_time, const char * szFormat /*= "%Y/%m/%d %H:%M:%S"*/)
根据 std::formatter 的 cppreference 文档,我们应该能够使用单独的标签来创建像 2021/03/24 15:36:32.123123
这样的字符串。但是,当 time_point 的持续时间使用微秒(这是我们使用的强制性要求)时,则会抛出 format_error.
如果我们将其拆分为单独的调用,以便我们分别使用日期和时间的格式,那么它就可以工作。像这样:
auto tSysTime = std::chrono::system_clock::now();
std::string sTime = std::format("{:%H:%M:%S}", tSysTime.time_since_epoch());
std::string sDate = std::format("{:%Y/%m/%d}", std::chrono::sys_days(std::chrono::duration_cast<std::chrono::days>(tSysTime.time_since_epoch())));
我是不是误解了什么,或者没有办法为我的目的使用单一格式字符串?请记住,格式字符串是一个可选参数,因此我不能对单个参数的拆分进行硬编码。
我的期望是写
std::format("{:%Y/%m/%d %H:%M:%S}",tSysTime.time_since_epoch());
但是,这会崩溃...
提前感谢您的帮助!
编辑:我在 Visual Studio 2019
中使用 /std::c++ 最新标志
你需要:
std::format("{:%Y/%m/%d %H:%M:%S}",tSysTime);
或者您可以将其简化为:
std::format("{:%Y/%m/%d %T}",tSysTime);
如果您的 system_clock::time_point::duration
不是 microseconds
,您可以使用以下命令将其强制为微秒精度:
std::format("{:%Y/%m/%d %T}",floor<microseconds>(tSysTime));
std::format("{:%Y/%m/%d %H:%M:%S}",tSysTime.time_since_epoch());
失败的原因是 .time_since_epoch()
将 time_point
变成了 duration
。 duration
s 对日期一无所知。例如,如果你问我当前的日期和时间是多少,而我告诉你 1,616,600,192,123,123µs,你会用奇怪的眼神看着我。 duration
对纪元一无所知。 duration
只是两个 time_point
之间的时间度量。
A time_point
另一方面,知道一个纪元。它包含一个 duration
并且意味着:这么多时间 duration
超出(或之前)我的时代。
std::format
理解time_point
和duration
的区别。因此,如果格式字符串要求日期(例如 %Y/%m/%d
),而您正在格式化 duration
,它会抛出一个异常,指示信息不足以完成请求的工作。但是如果你给它一个 time_point
,那么 std::format
知道如何从中获取日期信息。
这是 <chrono>
构建的类型安全设计的全部内容,因此可以尽早捕获尽可能多的逻辑错误。
int64_t i = 1'616'600'192'123'123;
microseconds d{i};
sys_time<microseconds> t{d};
cout << "i = " << i << '\n';
cout << "d = " << d << '\n';
cout << "t = " << t << '\n';
i
、d
和 t
在内存中都具有相同的值:1,616,600,192,123,123,但含义不同。当你打印出来时你可以看到这些不同的含义:
i = 1616600192123123
d = 1616600192123123µs
t = 2021-03-24 15:36:32.123123
这与:
没有什么不同
char x = 'A';
int y{x};
cout << "x = " << x << '\n'; // x = A
cout << "y = " << y << '\n'; // y = 65
假设我们有一个简单的函数,它使用给定的格式字符串获取 std::chrono::time_point 和 returns 字符串。像这样:
std::string DateTimeToString(std::chrono::sys_time, const char * szFormat /*= "%Y/%m/%d %H:%M:%S"*/)
根据 std::formatter 的 cppreference 文档,我们应该能够使用单独的标签来创建像 2021/03/24 15:36:32.123123
这样的字符串。但是,当 time_point 的持续时间使用微秒(这是我们使用的强制性要求)时,则会抛出 format_error.
如果我们将其拆分为单独的调用,以便我们分别使用日期和时间的格式,那么它就可以工作。像这样:
auto tSysTime = std::chrono::system_clock::now();
std::string sTime = std::format("{:%H:%M:%S}", tSysTime.time_since_epoch());
std::string sDate = std::format("{:%Y/%m/%d}", std::chrono::sys_days(std::chrono::duration_cast<std::chrono::days>(tSysTime.time_since_epoch())));
我是不是误解了什么,或者没有办法为我的目的使用单一格式字符串?请记住,格式字符串是一个可选参数,因此我不能对单个参数的拆分进行硬编码。
我的期望是写
std::format("{:%Y/%m/%d %H:%M:%S}",tSysTime.time_since_epoch());
但是,这会崩溃...
提前感谢您的帮助!
编辑:我在 Visual Studio 2019
中使用 /std::c++ 最新标志你需要:
std::format("{:%Y/%m/%d %H:%M:%S}",tSysTime);
或者您可以将其简化为:
std::format("{:%Y/%m/%d %T}",tSysTime);
如果您的 system_clock::time_point::duration
不是 microseconds
,您可以使用以下命令将其强制为微秒精度:
std::format("{:%Y/%m/%d %T}",floor<microseconds>(tSysTime));
std::format("{:%Y/%m/%d %H:%M:%S}",tSysTime.time_since_epoch());
失败的原因是 .time_since_epoch()
将 time_point
变成了 duration
。 duration
s 对日期一无所知。例如,如果你问我当前的日期和时间是多少,而我告诉你 1,616,600,192,123,123µs,你会用奇怪的眼神看着我。 duration
对纪元一无所知。 duration
只是两个 time_point
之间的时间度量。
A time_point
另一方面,知道一个纪元。它包含一个 duration
并且意味着:这么多时间 duration
超出(或之前)我的时代。
std::format
理解time_point
和duration
的区别。因此,如果格式字符串要求日期(例如 %Y/%m/%d
),而您正在格式化 duration
,它会抛出一个异常,指示信息不足以完成请求的工作。但是如果你给它一个 time_point
,那么 std::format
知道如何从中获取日期信息。
这是 <chrono>
构建的类型安全设计的全部内容,因此可以尽早捕获尽可能多的逻辑错误。
int64_t i = 1'616'600'192'123'123;
microseconds d{i};
sys_time<microseconds> t{d};
cout << "i = " << i << '\n';
cout << "d = " << d << '\n';
cout << "t = " << t << '\n';
i
、d
和 t
在内存中都具有相同的值:1,616,600,192,123,123,但含义不同。当你打印出来时你可以看到这些不同的含义:
i = 1616600192123123
d = 1616600192123123µs
t = 2021-03-24 15:36:32.123123
这与:
没有什么不同char x = 'A';
int y{x};
cout << "x = " << x << '\n'; // x = A
cout << "y = " << y << '\n'; // y = 65