"std::format"ing std::chrono 秒,不带小数位

xax*_*zak 6 c++ formatting stl c++-chrono c++20

在 c++20 中格式化秒(使用 std::format)而不显示小数位的正确方法是什么?


这段代码:

#include <chrono>
#include <format>
#include <iostream>

int main()
    {
        std::cout << std::format("{:%H:%M:%S}",  std::chrono::system_clock::now()) << std::endl;
        std::cout << std::format("{:%H:%M:%OS}", std::chrono::system_clock::now()) << std::endl;
    }
Run Code Online (Sandbox Code Playgroud)

产生此输出(通过主干 GCC (14.0.0 20230425)):

00:18:07.087240403
00:18:07.087622600
Run Code Online (Sandbox Code Playgroud)

我只想要整数部分(例如00:18:07没有尾随.087240403)。事后从结果字符串中删除剩余部分非常容易(或者手动提取秒数并单独打印它们),但如果这是预期的解决方案,我会感到非常惊讶。


此处描述了格式化代码。AFAICT 没有任何%S变体可以显式地将秒舍入或截断为最接近的整数。

%S(和下面的 %OS)的解释(来自上面的链接)是:

将秒写为十进制数。如果秒数小于 10,则结果以 0 为前缀。

如果输入的精度不能用秒精确表示,则格式是具有固定格式的十进制浮点数,其精度与输入的精度匹配(如果转换为浮点数,则为微秒精度)点小数秒不能在 18 个小数位以内)。小数点字符根据区域设置进行本地化。

修改后的命令 %OS 写入区域设置的替代表示形式。


GCC/glibc 在这里运行正常,对吗?(似乎符合上面的解释)。

如果是这样,实现这一目标的预期方法是什么?

  1. 我是否使用不同的格式字符串?
  2. 我使用不同的时钟吗?
  3. 我是否要先手动舍入该值?(如果四舍五入,它仍然显示小数部分)。
  4. 或者我真的必须手动删除小数部分或手动提取秒数。

如果这不是很容易实现,这是否可以被视为潜在的不良行为,也许是 STL 缺陷?)

康桓瑋*_*康桓瑋 10

您可以使用time_point_cast将其持续时间转换为seconds然后格式化它:

auto now = std::chrono::time_point_cast<std::chrono::seconds>(
             std::chrono::system_clock::now()
           );
std::cout << std::format("{:%H:%M:%S}", now) << std::endl;
Run Code Online (Sandbox Code Playgroud)

  • +1。附加信息:“floor&lt;秒&gt;”也有效,并且可以被认为是首选,因为它会在纪元之前和之后舍入。 (5认同)
  • 谢谢,这有效。但是,您认为应该有离散/整数秒的格式代码吗?因为这个解决方案看起来仍然不优雅。 (2认同)