将chrono :: duration类型转换为std :: tm类型

时间:2018-01-16 10:18:26

标签: c++ c++11 time chrono

我正在编写一个程序,从用户那里获取输入日期,使用它来初始化tm struct,然后使用chrono::time_points执行一些chrono::duration操作,例如获取年龄。

这是我的代码:

#include <iostream>
#include <chrono>
#include <ctime>
#include <iomanip>

using namespace std;

int main(){
  //representing a date
  tm *birthday  = new tm{00, 30, 00, 07, 11, 97};
  //convert to time t 
  time_t bt = mktime(birthday);
  //convert time_t to time_point
  chrono::system_clock::time_point t = chrono::system_clock::from_time_t(bt);
  chrono::system_clock::time_point now = chrono::system_clock::now();
  /*.. Testing 
  time_t nn = chrono::system_clock::to_time_t(now);
  time_t tnn = chrono::system_clock::to_time_t(t);
  */

  chrono::system_clock::duration lft = now - t;
  //convert to timepoint
  chrono::system_clock::time_point tlft{lft};
  time_t lifetime = chrono::system_clock::to_time_t(tlft);
  cout << put_time(localtime(&lifetime), "%F %T") << endl;

  return 0;
}

我的输出是这样的:
     $> 1990-02-10 09:42:46

所以,根据我的理解,它在刻度线上执行简单的数学减法并使用localtime,将其转换为EPOCH之后的日期,这就是它给我1990年的原因。我想知道,是否有任何方式,将持续时间直接转换为struct tm,以便我得到20年的东西?

1 个答案:

答案 0 :(得分:2)

以下是以您选择的单位提取持续时间的方法:

std::chrono::duration<double> lft = now - t;
using year = std::chrono::duration<int, std::ratio<31557600>>;
auto nby = std::chrono::duration_cast<year>(lft);
std::cout << nby.count() << "\n";

考虑到这一点,我建议实施以下的品味:

struct Age
{
    using year   = std::chrono::duration<int, std::ratio<31'557'600>>;
    using month  = std::chrono::duration<int, std::ratio< 2'592'000>>;
    using day    = std::chrono::duration<int, std::ratio<    86'400>>;
    using hour   = std::chrono::hours;
    using minute = std::chrono::minutes;
    using second = std::chrono::seconds;

    Age(std::chrono::system_clock::time_point birth)
        : _age(std::chrono::system_clock::now() - birth)
    {}

    template<class Duration>
    auto extract()
    {
        const auto result = std::chrono::duration_cast<Duration>(_age);
        _age -= result;
        return result;
    }

    friend std::ostream& operator<<(std::ostream& os, Age age)
    {
         const auto years   = age.extract<year>();
         const auto monthes = age.extract<month>();
         const auto days    = age.extract<day>();
         const auto hours   = age.extract<hour>();
         const auto minutes = age.extract<minute>();
         const auto seconds = age.extract<second>();

         return os  << years.count()
                    << ":" << std::setw(2) << std::setfill('0') << monthes.count()
                    << ":" << std::setw(2) << std::setfill('0') << days.count()
                    << " " << std::setw(2) << std::setfill('0') << hours.count()
                    << ":" << std::setw(2) << std::setfill('0') << minutes.count()
                    << ":" << std::setw(2) << std::setfill('0') << seconds.count()
                    ;
    }

private:
    std::chrono::duration<double> _age;
};

打印20:01:10 12:43:40 with your example date (live demo)