使用C ++获取Unix时间戳


71

如何uint在C ++中获得Unix时间戳?我已经用Google搜索了一下,似乎大多数方法都在寻找更复杂的方法来表示时间。我不能只是把它当作uint

Answers:


90

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时代。Linux联机帮助页在这里

上面链接的cppreference页面给出了以下示例

#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";
}

4
当然,“ Epoch”是Unix和Linux上的Unix eproch,但这不是通用的。
MSalters 2011年

43
#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;
}

1
这是假设std::time()您从1970年以来就拥有了几秒钟的时间。在许多系统(我相信POSIX和Windows)上都是如此,但是语言标准并不能保证。
基思·汤普森

17

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

更糟糕的是,您也无法轻易地弄清楚。当然,您可以找到time_t(0)带有的日历日期gmtime,但是如果那样的话您将怎么办2000-01-01T00:00Z1970-01-01T00:00Z与之间有多少秒2000-01-01T00:00Z?由于leap秒,它肯定不是60的倍数。


1
“如何在C ++中获得uint Unix时间戳?” -给定-如您所说-您可以gmtime()稍后调用以获取该时间戳编码的任何内容的可读表示,无论time()参考日期或间隔计算的适用性如何,问题中要求的功能均不满足?
托尼·德罗伊

3
要在非UNIX系统上获得UNIX时间戳,您必须知道本地纪元和之间的差异(以秒为单位)1970-01-01T00:00Z。只是没有方法可以做到这一点。
MSalters

由于某种原因,我给人的印象是,问题是在UNIX(或Linux等)计算机上的代码,但是现在我知道您来自哪里。好奇:您是否找到了time_t(0)不是1970-01-01T00:00Z的任何实际系统?只需几分钟就可以计算出任何给定系统上的偏移量(采用非UNIX time_t(0)并在UNIX系统上获得time_t),但是感谢您的解释。
Tony Delroy,2012年

6
对于VS它的UNIX时间;MSDN指出:时间函数根据系统时钟返回自协调世界时(UTC)1970年1月1日午夜(00:00:00)起经过的秒数。 msdn.microsoft.com/en-us/library/1f4c8f33.aspx
Oliver Zendel 2014年

2
@TonyD:IBM系统显然是一个例外。毫不奇怪,因为他们早在1970年1月1日之前就从事计算机业务。
MSalters 2015年

8

由于这是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,请自担风险。


3
纪元将在C ++ 20中得到正式认可: eel.is/c++draft/time.clock.system.overview
Howard

6
#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?为什么要使用<sys/time.h>而不是标准<time.h>
基思·汤普森

我理解,但我认为time.h和sys / time.h都存在于任何posix兼容的操作系统中。同样完全正确的是,time_t也可以是负值,因为它表示为从1970-01-01T00:00Z开始经过的秒数。
anijhaw


4

我创建了具有更多信息的全局定义:

#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

3
@Troyseph因为那样__FILE__``__FUNCTION__``__LINE__ 将无法正常工作。这是一个宏。
xinthose

1
很公平!
感到遗憾的
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.