如何将纳秒纪元时间戳转换为可读格式

时间:2019-06-24 21:34:49

标签: c++ unix-timestamp

我有一个很长的整数,代表一个具有纳秒精度的纪元时间戳,我想将其转换为人类可读的时间戳,例如date-hh:mm:ss

我尝试使用静态强制转换并将此整数直接强制转换为time_t格式,并打算使用localtime对其进行格式化,但未成功。

从文档看来,time_ts是一个32位整数,这意味着它不足以读取我的时间戳。将时间戳格式化为人类可读格式的最佳方法是什么?

#include <iostream>
#include <sstream>
#include <locale>
#include <iomanip>
#include <ctime>

int main()
{
   time_t now = time(NULL);
   long long int ts = 1561402947698860015;

   time_t t = static_cast<time_t>(ts);
   std::cout << std::asctime(std::localtime(&t))
          << t << " seconds since the Epoch\n";
   std::cout<<"done"<<std::endl;
   return 0;
}

2 个答案:

答案 0 :(得分:1)

选项1

一个简单的强制转换不会知道需要将数字的缩放比例从纳秒转换为秒(因为秒几乎总是time_t使用的增量)。对于编译器来说,只是将一个整数分配给另一个整数,甚至可能是同一类型。如果您的时间以纳秒为单位,并且想要使用time_t,则可能需要除以1,000,000,000,才能将图章转换为秒。

#include <iostream>
#include <sstream>
#include <locale>
#include <iomanip>
#include <ctime>

constexpr long long int nanos_to_seconds = 1000000000; // conversion factor
constexpr long long int nanos_to_milis = 1000000;

int main()
{
   time_t now = time(NULL);
   long long int ts = 1561402947698860015;

   time_t t = static_cast<time_t>(ts/nanos_to_seconds);
                                  //^ change here
   long long int milis = ts % nanos_to_seconds / nanos_to_millis; // compute milliseconds
   std::cout << std::asctime(std::localtime(&t))
             << t << "." << std::setfill('0') << std::setw(3) << millis
             << " seconds since the Epoch\n";
   std::cout<<"done"<<std::endl;
   return 0;
}

选项2

从C ++ 11开始,C ++在the <chrono> library中内置了对纳秒级时间戳的支持。将其与Howard Hinnant's date library结合使用,即可解决所有格式方面的问题,并为C ++ 20准备好代码。这值得研究。它不能立即解决您当前的问题,但可以用来替代问题,以免日后烦人。

旁注:

这几天time_t通常是64位秒数。 32位计数器将在另外20年左右的时间内推出,因此与其在最后一分钟不得不忍受Y2038错误,不如在几十年前开始转移到更大的数量。

答案 1 :(得分:0)

如果您将其转换为秒(如user4581301所述),您的代码将起作用:

long long int ts = 1561402947698860015 / 1000000000;

而且,不要使用:

std::asctime(std::localtime(&t))

您可以使用以下命令获得相同的结果:

ctime(&t)