C ++没有日期的时间?

时间:2019-06-23 06:15:51

标签: c++ time

在C ++中处理没有日期的时间点的最佳方法是什么?

我有没有日期的时间戳。时间戳记是24小时军事时间,没有日期,时区或其他信息。时间戳记存储为字符串。

我需要完成两项任务:

  1. 存储由时间戳表示的时间数据。
  2. 计算时间之间的差异。

我知道C ++具有带时间数据结构的库。其中一些数据结构包含有关日期的信息。如果可能的话,我不想使用这些类型的数据结构,因为我的数据不包括日期。我想要的功能类似于

中的时间数据结构
  • Boost.Date_Time
  • chrono
  • ctime

,但不存储日期或24小时军事时间(无论是明示的还是隐含的)。

我希望时间点对象不存储有关日期或24小时军事时间以外的任何信息。我想

  1. 将时间戳记字符串放到这些对象上。

然后

  1. 查找结果时间点之间的差异(时间点之间的持续时间)。

完成此任务的最佳方法是什么?

我的理想解决方案涉及一个已经存在的标准库或Boost库,并且避免存储有关日期,时区或24小时军事时间以外的任何信息。我可能已经忽略了我已经提到的一个库(即Boost.Date_Time,chrono或ctime)可能满足了我的需求。

1 个答案:

答案 0 :(得分:1)

一个想法是创建一个自定义的chrono时钟(可能称为time_of_day_clock),然后在其旁边创建一个chrono::time_point s系列。或者,也许您只需要seconds精度时间(您对此还不清楚)。在这样的时钟上创建seconds精度time_point所需的一切:

struct time_of_day_clock {};
using time_of_day = std::chrono::time_point<time_of_day_clock,
                                            std::chrono::seconds>;

现在,您可以创建几个辅助函数,以在std::stringtime_of_day之间进行投射:

// Assume t is of the form HH:MM:SS
time_of_day
to_time_of_day(const std::string& t)
{
    using namespace std::chrono;
    auto parse = [&t](auto i) -> int
        {
            return (t[i]-'0')*10 + (t[i+1]-'0');
        };
    hours h{parse(0)};
    minutes m{parse(3)};
    seconds s{parse(6)};
    return time_of_day{h+m+s};
}

// Format to HH:MM:SS
std::string
to_string(const time_of_day& t)
{
    using namespace std;
    using namespace std::chrono;
    auto s = t.time_since_epoch();
    assert(s >= 0s);
    assert(s < 86400s);
    auto h = duration_cast<hours>(s);
    s -= h;
    auto m = duration_cast<minutes>(s);
    s -= m;
    string r = "00:00:00";
    auto print = [&r](auto i, auto j)
        {
            for (++j; i != 0; i /= 10, --j)
                r[j] = i % 10 + '0';
        };
    print(h.count(), 0);
    print(m.count(), 3);
    print(s.count(), 6);
    return r;
}

现在,您拥有执行以下操作的所有工具:

int
main()
{
    auto t1 = to_time_of_day("17:15:23");
    auto t2 = to_time_of_day("07:14:06");
    std::cout << "t1 = " << to_string(t1) << '\n';
    std::cout << "t2 = " << to_string(t2) << '\n';
    auto d = t1 - t2;
    std::cout << d.count() << "s\n";
    auto t3 = t2 + d;
    std::cout << "t3 = " << to_string(t3) << '\n';
}

输出:

t1 = 17:15:23
t2 = 07:14:06
36077s
t3 = 17:15:23

这为您提供类型安全性:一天的时间不会与持续时间混淆,但它们会与有理代数互操作

根据您的应用程序的需要,在上面添加尽可能多的错误检查。

上面的计划有一个小小的障碍:语言律师可能会抱怨整个事情都是不确定的行为,因为time_of_day_clock不满足计时要求。

现实情况是,除非您尝试在now()上调用time_of_day_clock或将time_of_day与尝试执行此操作的算法一起使用(或尝试访问嵌套的方法),否则事情将一直有效。 time_of_day_clock的类型)。而且,如果您不小心这样做了,结果将是编译时错误,而不是运行时错误,以及未定义的行为。

我认为对Clock的{​​{1}}模板参数的要求过于严格,并将尝试将其降低到将来的标准中的实际要求