【问题标题】:Get Unix timestamp with C++使用 C++ 获取 Unix 时间戳
【发布时间】:2011-08-26 03:23:09
【问题描述】:

如何在 C++ 中获得 uint unix 时间戳?我用谷歌搜索了一下,似乎大多数方法都在寻找更复杂的方式来表示时间。我不能把它作为uint 吗?

【问题讨论】:

    标签: c++ unix timestamp uint


    【解决方案1】:

    C++20 引入了一个保证 time_since_epoch 是相对于 UNIX 纪元的,cppreference.com 给出了一个我已经提炼到相关代码的示例,并改为以秒为单位而不是小时:

    #include <iostream>
    #include <chrono>
     
    int main()
    {
        const auto p1 = std::chrono::system_clock::now();
     
        std::cout << "seconds since epoch: "
                  << std::chrono::duration_cast<std::chrono::seconds>(
                       p1.time_since_epoch()).count() << '\n';
    }
    

    使用 C++17 或更早版本,time() 是最简单的函数 - 自 Epoch 以来的秒数,对于 Linux 和 UNIX,至少是 UNIX 纪元。 Linuxmanpage here.

    上面链接的 cppreference 页面给出了这个example

    #include <ctime>
    #include <iostream>
     
    int main()
    {
        std::time_t result = std::time(nullptr);
        std::cout << std::asctime(std::localtime(&result))
                  << result << " seconds since the Epoch\n";
    }
    

    【讨论】:

    • “Epoch”当然是 Unix 和 Linux 上的 Unix 纪元,但这不是通用的。
    • 请注意std::chrono::secondsis defined asduration&lt;/*signed integer type of at least 35 bits*/&gt;。所以例如一个 32 位的 int 可能还不够。
    【解决方案2】:
    #include<iostream>
    #include<ctime>
    
    int main()
    {
        std::time_t t = std::time(0);  // t is an integer type
        std::cout << t << " seconds since 01-Jan-1970\n";
        return 0;
    }
    

    【讨论】:

    • 这假设 std::time() 自 1970 年以来为您提供秒数。这在很多系统上都是如此(我相信 POSIX 和 Windows),但语言标准并不能保证。
    【解决方案3】:
    #include <iostream>
    #include <sys/time.h>
    
    using namespace std;
    
    int main ()
    {
      unsigned long int sec= time(NULL);
      cout<<sec<<endl;
    }
    

    【讨论】:

    • time() 返回time_t 类型的结果,原则上可以是有符号、无符号甚至是浮点数。为什么将结果存储在long int 中?为什么使用&lt;sys/time.h&gt; 而不是标准的&lt;time.h&gt;
    • 我理解,但我认为在任何符合 posix 的操作系统中 time.h 和 sys/time.h 都存在。此外,您完全正确的是 time_t 也可以是负值,因为它表示为从 1970-01-01T00:00Z 过去的秒数。
    【解决方案4】:

    最常见的建议是错误的,你不能只依赖time()。这用于相对时间:ISO C++ 没有指定 1970-01-01T00:00Ztime_t(0)

    更糟糕的是,您也无法轻易弄清楚。当然,你可以用gmtime 找到time_t(0) 的日历日期,但是如果是2000-01-01T00:00Z,你会怎么做? 1970-01-01T00:00Z2000-01-01T00:00Z 之间有多少秒?由于闰秒,它肯定不是 60 的倍数。

    【讨论】:

    • "如何在 C++ 中获得一个 uint unix 时间戳?" - 给定 - 正如您所说 - 您可以稍后调用 gmtime() 以获得时间戳编码的任何内容的可读表示,time() 不满足问题中请求的功能,无论参考日期或适用性如何区间计算?
    • 要在非 UNIX 系统上获得 UNIX 时间戳,您必须知道本地 epoch 和 1970-01-01T00:00Z 之间的差异(以秒为单位)。没有任何方法可以做到这一点。
    • 出于某种原因,我的印象是问题是针对 UNIX(或 Linux 等)机器上的代码,但现在我知道您来自哪里了。好奇:你有没有发现 time_t(0) 不是 1970-01-01T00:00Z 的实际系统?只需几分钟即可计算出任何给定系统上的偏移量(取非 UNIX time_t(0) 并在 UNIX 系统上为其获取 time_t),但感谢您解释您的担忧。
    • 对于 VS 它的 UNIX 时间; MSDN 声明: time 函数根据系统时钟返回自 1970 年 1 月 1 日午夜 (00:00:00) 以来经过的秒数,协调世界时 (UTC)。 msdn.microsoft.com/en-us/library/1f4c8f33.aspx
    • @TonyD:IBM 系统显然是个例外。这并不奇怪,因为他们早在 1970 年 1 月 1 日之前就从事计算机业务。
    【解决方案5】:

    Windows 使用不同的纪元和时间单位:请参阅 Convert Windows Filetime to second in Unix/Linux

    std::time() 在 Windows 上返回的内容(到目前为止)对我来说是未知的 (;-))

    【讨论】:

      【解决方案6】:

      我创建了一个包含更多信息的全局定义:

      #include <iostream>
      #include <ctime>
      #include <iomanip>
      
      #define __FILENAME__ (__builtin_strrchr(__FILE__, '/') ? __builtin_strrchr(__FILE__, '/') + 1 : __FILE__)    // only show filename and not it's path (less clutter)
      #define INFO std::cout << std::put_time(std::localtime(&time_now), "%y-%m-%d %OH:%OM:%OS") << " [INFO] " << __FILENAME__ << "(" << __FUNCTION__ << ":" << __LINE__ << ") >> "
      #define ERROR std::cout << std::put_time(std::localtime(&time_now), "%y-%m-%d %OH:%OM:%OS") << " [ERROR] " << __FILENAME__ << "(" << __FUNCTION__ << ":" << __LINE__ << ") >> "
      
      static std::time_t time_now = std::time(nullptr);
      

      像这样使用它:

      INFO << "Hello world" << std::endl;
      ERROR << "Goodbye world" << std::endl;
      

      样本输出:

      16-06-23 21:33:19 [INFO] main.cpp(main:6) >> Hello world
      16-06-23 21:33:19 [ERROR] main.cpp(main:7) >> Goodbye world
      

      将这些行放在头文件中。我发现这对于调试等非常有用。

      【讨论】:

      • 为什么是#define 而不是函数?函数会更灵活,可重载,使用起来更明显......
      • @Troyseph 因为那样__FILE__``__FUNCTION__``__LINE__ 将无法按预期工作。这是一个宏。
      • 很公平!可惜没有更现代的选择=]
      【解决方案7】:

      由于这是 google 上的第一个结果并且还没有 C++20 的答案,这里是如何使用 std::chrono 来做到这一点:

      #include <chrono>
      
      //...
      
      using namespace std::chrono;
      int64_t timestamp = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
      

      在 20 之前的 C++ 版本中,system_clock 的纪元是 Unix 纪元是事实上的约定,但它不是标准化的。如果您未使用 C++20,请自行承担使用风险。

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-12-08
      • 2017-10-14
      • 1970-01-01
      • 2012-03-04
      • 2020-10-22
      • 1970-01-01
      相关资源
      最近更新 更多