C ++如何减去两个时间变量

时间:2018-02-16 01:14:40

标签: c++11 chrono

我有一堆时间变量,格式为“day-month-year H:M”,例如14-03-15 15:25。如何正确测量两个时间变量之间的差异并输出持续时间类型?

std::string t1 = 14-03-15 15:25;
std::string t2 = 19-05-15 7:32;

template <typename Duration>
auto diff(std::string& t1, std::string& t2) {
   // How to do from here?
} 

auto ds = diff<std::chrono::seconds>(t1, t2);
auto dm = diff<std::chrono::minutes>(t1, t2);

2 个答案:

答案 0 :(得分:3)

这个问题很有意思,因为它揭示了关于时间的模糊问题。

t1t2代表UTC时间吗?或时区?如果是后者,计算机的当前本地时区,还是某个其他时区?

虽然对于这些输入不太重要,但对于秒精度计算,闰秒是否重要?

每个问题的答案都会影响结果。目前的C和C ++标准API不足以解决这些问题的全部问题。

This library可以为您提供正确的结果,但根据上述问题,可以根据所需的输入解释给出不同的答案。

对于最简单的解释:这些时间代表UTC和闰秒并不重要:

#include "date/date.h"
#include <chrono>
#include <iostream>
#include <sstream>
#include <stdexcept>
#include <string>

std::string t1 = "14-03-15 15:25";
std::string t2 = "19-05-15 7:32";

template <typename Duration>
auto
diff(const std::string& t1, const std::string& t2)
{
    using namespace std;
    using namespace date;
    istringstream in{t1};
    sys_time<Duration> d1;
    in >> parse("%d-%m-%y %H:%M", d1);
    if (in.fail())
        throw runtime_error("didn't parse " + t1);
    in.clear();
    in.str(t2);
    sys_time<Duration> d2;
    in >> parse("%d-%m-%y %H:%M", d2);
    if (in.fail())
        throw runtime_error("didn't parse " + t2);
    return d2 - d1;
}

int
main()
{
    using date::operator<<;
    auto ds = diff<std::chrono::seconds>(t1, t2);
    std::cout << ds <<  '\n';
    auto dm = diff<std::chrono::minutes>(t1, t2);
    std::cout << dm <<  '\n';
}

输出是:

5674020s
94567min

对于略有不同的输入,计算假设输入在“America / New_York”中,输出将是不同的。如果t1在01-01-15之前漂移,那么闰秒的问题会影响输出。

如果输入解释的这些细节很重要,那么您几乎可以保证使用现有的C / C ++ API来计算错误(但只是轻微且极少 - 最危险的类型)。

答案 1 :(得分:1)

解决了将字符串转换为时间的问题

std::tm tm = {};
strptime(t1.c_str(), "%d-%m-%y %H:%M", &tm);
auto tp1 = std::chrono::system_clock::from_time_t(std::mktime(&tm));

或者

// floating-point duration: no duration_cast needed
std::chrono::duration<double, Duration> duration = tp2 - tp1;

你可以减去时钟。

{{1}}