C++ C+的缺点+;20标准::计时::持续时间格式

C++ C+的缺点+;20标准::计时::持续时间格式,c++,formatting,std,chrono,c++20,C++,Formatting,Std,Chrono,C++20,我需要以易读的方式打印可能大于24小时的std::chrono::duration,如“2d.09:10:11” C++20的std::chrono::time\u point和std::chrono::duration(基于Howard Hinnant的)包含大量有用的格式说明符,但在std::chrono::duration中没有一个用于天数的格式说明符。最近的一个是%j,但它用零填充。此外,对于一天中的小时数也没有规定。最接近的是%H(但它也包括全天小时)和%OH(但它在小时数小于24的断

我需要以易读的方式打印可能大于24小时的
std::chrono::duration
,如
“2d.09:10:11”

C++20的
std::chrono::time\u point
std::chrono::duration
(基于Howard Hinnant的)包含大量有用的格式说明符,但在
std::chrono::duration
中没有一个用于天数的格式说明符。最近的一个是
%j
,但它用零填充。此外,对于一天中的小时数也没有规定。最接近的是
%H
(但它也包括全天小时)和
%OH
(但它在小时数小于24的断言中崩溃)

我错过什么了吗

在C++20的
std::format
中添加更多说明符有意义吗

到目前为止,我正在使用:

#包括
#include//std::strncmp
#包括//使用Howard Hinnant的日期库,直到编译器支持C++20
#包括
//解决C++20 std::chrono::format无法在std::chrono::duration中生成天数的问题。
//此文件的临时格式说明符为“%J”。它必须位于格式字符串的开头。
模板
std::string duration_to_str(const char*格式,const std::chrono::duration&duration)
{
if(std::strncmp(格式,“%J”,2))
返回日期::格式(格式、持续时间);
静态常数自动一天=标准时间:小时(24);
const size\u t days=std::chrono::duration\u cast(duration).count()/24;
返回std::to_字符串(天)+日期::格式(格式+2,持续时间-天*一天);
}
测试:

#包括
模板
无效测试(常数标准::计时::持续时间和持续时间)
{

std::cout您只需对std::chrono::days进行
持续时间

template<typename Rep, typename Period>
std::string duration_to_str(const char* format, const std::chrono::duration<Rep, Period>& duration)
{
    if (std::strncmp(format, "%J", 2))
        return date::format(format, duration);

    auto num_days = std::chrono::duration_cast<date::days>(duration);
    return std::to_string(num_days.count()) + date::format(format + 2, duration - num_days);
}
模板
std::string duration_to_str(const char*格式,const std::chrono::duration&duration)
{
if(std::strncmp(格式,“%J”,2))
返回日期::格式(格式、持续时间);
自动天数=标准::计时::持续时间(持续时间);
返回std::to_字符串(num_days.count())+date::format(format+2,duration-num_days);
}
至于它不存在的原因,
chrono
的日期/时间格式化的目的是格式化日期和时间。格式化生成年份和该年份天数的日期是一种类似日期的操作。格式化生成年份、月份和该月份天数的日期也是一种类似日期的操作然而,持续时间内的天数实际上并不像格式化操作那样是一个日期

这与获取持续时间内的小时数和持续时间包含的24小时时间之间的差异是一样的。前者不考虑任何时间上下文;您只获取持续时间内的小时数。也没有格式字段。

我想展示一种变通方法正如Howard Hinnant在其评论中所建议的那样,对于那些可能觉得有用的人来说:

#包括
#include//std::strncmp
#包括//使用Howard Hinnant的日期库,直到编译器支持C++20
#包括
模板
std::string duration_to_str(const char*格式,const std::chrono::duration&duration)
{
if(std::strncmp(格式,“%J”,2))
返回日期::格式(格式、持续时间);
const auto days=std::chrono::duration\u cast(持续时间);
返回std::to_字符串(days.count())+date::format(format+2,duration-days);
}

你说的有些道理,但我觉得有点不一致。让我们以“17:18:19”为例,它是62299秒。
%H
是完整的小时数。
%M
是剩余的完整分钟数(而不是原始时间值)在删除小时数之后。等等。现在我们有了
%j
,这是一年中的天数,但我们没有办法打印剩余的部分时间(在减少了这个天数之后)。另外,感谢您的建议!
一天
var仍然在使用(您删除了它)。不仅是一种利用
天数
做你想做的事情的方法,还缺少其他单位,如
Ks
Ms
Gs
。最终,在扩展
strftime
格式标志时,设计是非常保守的解决方法是完全按照您正在做的事情来做:使用chrono来分离您想要的单位,然后根据需要格式化从这些单位中提取的数字。如果
day\u count
的类型是
days
,而不是
int
,那么表达式
duration-day\u count*one\u day
将简化为
dur>ation-day\u count
。然后您可以发送
day\u count.count()
to
to\u string
。这也完全消除了对
one\u day
常量的需要。@HowardHinnant,谢谢,我想尝试一下正确的方法。那么你在我的%J参数中找到了逻辑吗?@HowardHinnant顺便说一句,我在你的日期库文档页面上发现了一个输入错误,我想提出拉取请求并进行修复,但是注意到站点的内容比相应的github repo内容更新。因此键入的是:替换
%Ex生成区域设置的备用时间
,替换为
%Ex生成区域设置的备用时间
(小写x到大写x)。不要在问题中添加答案。如果您想自己回答问题,请将其作为答案发布。我根据您和Howard的建议在我的问题中添加了简化代码,原因有两个:1.该代码不是我问题的答案,而是我面临的问题的解决方法。2.您答案中的代码没有编译。现在您已修复了它,但它是g结果不正确。您可以发布自己问题的答案,甚至可以接受。但您必须使用页面底部的“添加答案”按钮将其作为答案发布
template<typename Rep, typename Period>
std::string duration_to_str(const char* format, const std::chrono::duration<Rep, Period>& duration)
{
    if (std::strncmp(format, "%J", 2))
        return date::format(format, duration);

    auto num_days = std::chrono::duration_cast<date::days>(duration);
    return std::to_string(num_days.count()) + date::format(format + 2, duration - num_days);
}