C ++ 20 std :: chrono :: duration格式的缺点

问题描述 投票:0回答:1

我需要以易于阅读的方式打印std::chrono::duration,可能会超过24小时,例如"2 d. 09:10:11"

C ++ 20的std::chrono::time_pointstd::chrono::duration formatting(基于Howard Hinnant的date library)包含大量有用的格式说明符,但在std::chrono::duration中没有天数。最接近的是%j,但会用零填充。也没有一天中小时数的说明符。最接近的是%H(但也包括整天的小时数)和%OH(但在断言小时数少于24时崩溃)。

我想念什么吗?

向C ++ 20的std::format添加更多说明符是否有意义?

到目前为止,我正在使用workaround function

#include <chrono>
#include <cstring> // std::strncmp
#include <date.h> // use Howard Hinnant's date library until C++20 is supported by compilers
#include <string>

// Workaround for C++20 std::chrono::format's inability to produce number of days in std::chrono::duration.
// Temporary format specifier for this is `%J`. It must be in the beginning of the format string.
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);
    static const auto one_day = std::chrono::hours(24);
    const size_t days = std::chrono::duration_cast<std::chrono::hours>(duration).count() / 24;
    return std::to_string(days) + date::format(format + 2, duration - days * one_day);
}

测试:

#include <iostream>

template<typename Rep, typename Period>
void test_dur_to_str(const std::chrono::duration<Rep, Period>& duration)
{
    std::cout << duration_to_str("%T", duration) << ":\n"
              << duration_to_str("%j d. %T", duration) << '\n'
              << duration_to_str("%J d. %T", duration) << "\n\n";
}

int main()
{
    test_dur_to_str(std::chrono::seconds(24 * 60 * 60 - 1));
    test_dur_to_str(std::chrono::seconds(24 * 60 * 60));
    test_dur_to_str(std::chrono::seconds(91297));
    test_dur_to_str(std::chrono::seconds(2 * 24 * 60 * 60 - 1));
    test_dur_to_str(std::chrono::seconds(2 * 24 * 60 * 60));
    test_dur_to_str(std::chrono::seconds(2 * 24 * 60 * 60 + 1));
    test_dur_to_str(std::chrono::seconds(13 * 24 * 60 * 60 + 5));
    test_dur_to_str(std::chrono::seconds(365 * 24 * 60 * 60 + 5));
    test_dur_to_str(std::chrono::seconds(366 * 24 * 60 * 60 + 5));
    test_dur_to_str(std::chrono::seconds(367 * 24 * 60 * 60 + 5));
}

输出:

23:59:59:
000 d. 23:59:59
0 d. 23:59:59

24:00:00:
001 d. 24:00:00
1 d. 00:00:00

25:21:37:
001 d. 25:21:37
1 d. 01:21:37

47:59:59:
001 d. 47:59:59
1 d. 23:59:59

48:00:00:
002 d. 48:00:00
2 d. 00:00:00

48:00:01:
002 d. 48:00:01
2 d. 00:00:01

312:00:05:
013 d. 312:00:05
13 d. 00:00:05

8760:00:05:
365 d. 8760:00:05
365 d. 00:00:05

8784:00:05:
366 d. 8784:00:05
366 d. 00:00:05

8808:00:05:
367 d. 8808:00:05
367 d. 00:00:05
c++ formatting std chrono c++20
1个回答
0
投票

您可以只将duration_cast设为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 day_count = std::::chrono::duration_cast<std::chrono::days>(duration).count();
    return std::to_string(day_count) + date::format(format + 2, duration - days * one_day);
}

关于为什么它不存在,chrono的日期/时间格式化的目的是格式化日期和时间。格式化日期以生成年份和该年中的天数是类似于日期的操作。格式化日期以生成年,月和该月中的天数也是类似于日期的操作。但是,持续时间中的天数并不是真正的类似于日期的格式化操作。

与获得持续时间中的小时数与持续时间中所包含的24小时之间的区别是一样的。前者是在不考虑任何时间上下文的情况下完成的。您只是获得持续时间的小时数。也没有that的格式字段。

© www.soinside.com 2019 - 2024. All rights reserved.