【问题标题】:How to convert nano second epoch timestamp to readable format如何将纳秒纪元时间戳转换为可读格式
【发布时间】:2019-11-06 17:06:16
【问题描述】:

我有一个 long long 整数,表示具有纳秒精度的纪元时间戳,我想将其转换为人类可读的时间戳,例如 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;
}

【问题讨论】:

标签: c++ unix-timestamp


【解决方案1】:

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

long long int ts = 1561402947698860015 / 1000000000;

但也不要使用:

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

您可以使用以下方法获得相同的结果:

ctime(&t)

【讨论】:

    【解决方案2】:

    选项 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 &lt;chrono&gt; library 中内置了对纳秒时间戳的支持。将此与Howard Hinnant's date library 结合使用,您的所有格式问题都会得到解决,同时让您的代码为 C++20 做好准备。这是值得研究的。它不能开箱即用地解决您当前的问题,但可以用来替换问题,以便将来不那么烦人。

    旁注:

    如今time_t 通常是 64 位的秒数。 32 位计数器将在另外 20 年左右推出,因此与其在最后一刻忍受 Y2038 错误,不如在几十年前开始转向更大的数字。

    【讨论】:

    • 感谢您的帮助,是否可以实现更高的精度,例如通过 localtime 获取毫秒部分? static_cast 似乎将时间戳截断为秒,因此失去精度。
    • time_t (通常)只不过是一个 64 位有符号整数计数秒。你不能得到小数秒。如果您想要小数秒,您可以使用适当的零填充添加 ts%nanos_to_seconds,但这听起来更像是您想要探索选项 2。请参阅更新以回答。
    • 关于更高精度的答案:是的,选项 2:1561402947698860015 在我的本地时区格式化为 2019-06-24 15:02:27.698860015。如果你只想要毫秒精度,那也很容易被截断。
    猜你喜欢
    • 1970-01-01
    • 2013-03-17
    • 1970-01-01
    • 1970-01-01
    • 2017-12-06
    • 2021-12-11
    • 2021-10-23
    • 1970-01-01
    相关资源
    最近更新 更多