std :: string到std :: chrono time_point

时间:2014-08-19 22:00:11

标签: c++ c++11 casting chrono

我有一个以下时间格式的字符串:

"%Y-%m-%d %H:%M:%S.%f"

其中%f是毫秒,例如:14:31:23.946571

我想将此作为chrono time_point。是否有演员这样做?

1 个答案:

答案 0 :(得分:6)

std::stringstd::chrono::time_point没有演员表。您必须构建std::chrono::time_point对象。

  • 使用除微秒之外的所有内容构建std::tm对象(<ctime>)。 年份应该基于1900而不是0.月份应该基于0而不是1.
  • 使用std::mktime()创建std::time_t对象。
  • 使用std::chrono::time_point创建from_time_t()
  • 将剩余的小数部分(视为int)作为std::chrono::microsecond()期限添加到time_point

请注意,<iomanip>函数std::ctime()std::put_time()不知道精度低于一秒。如果要打印该精度级别,则需要编写一个函数来执行此操作。

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

struct Tm : std::tm {
  int tm_usecs; // [0, 999999] micros after the sec

  Tm(const int year, const int month, const int mday, const int hour,
     const int min, const int sec, const int usecs, const int isDST = -1)
      : tm_usecs{usecs} {
    tm_year = year - 1900; // [0, 60] since 1900
    tm_mon = month - 1;    // [0, 11] since Jan
    tm_mday = mday;        // [1, 31]
    tm_hour = hour;        // [0, 23] since midnight
    tm_min = min;          // [0, 59] after the hour
    tm_sec = sec;          // [0, 60] after the min
                           //         allows for 1 positive leap second
    tm_isdst = isDST;      // [-1...] -1 for unknown, 0 for not DST,
                           //         any positive value if DST.
  }

  template <typename Clock_t = std::chrono::high_resolution_clock,
            typename MicroSecond_t = std::chrono::microseconds>
  auto to_time_point() -> typename Clock_t::time_point {
    auto time_c = mktime(this);
    return Clock_t::from_time_t(time_c) + MicroSecond_t{tm_usecs};
  }
};

int main() {
  using namespace std::chrono;

  auto tp_nomicro = Tm(2014, 8, 19, 14, 31, 23, 0).to_time_point();
  auto tp_micro = Tm(2014, 8, 19, 14, 31, 23, 946571).to_time_point();
  std::cout << duration_cast<microseconds>(tp_micro - tp_nomicro).count()
            << " microseconds apart.\n";

  auto time_c = high_resolution_clock::to_time_t(tp_micro);
  std::cout << std::ctime(&time_c) << '\n';
}