如何在C++中获取uint
的Unix时间戳?我已经搜索了一些资料,似乎大多数方法都在寻找更加复杂的时间表示方式。我是否可以直接获得它作为一个uint
?
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 manpage。
上面链接的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";
}
#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)上是正确的,但这并不受语言标准的保证。 - Keith Thompson最常见的建议是错误的,你不能仅仅依靠time()
。它用于相对时间计算:ISO C++没有规定1970-01-01T00:00Z
是time_t(0)
。
更糟糕的是,你也无法轻松地弄清楚它。当然,你可以使用gmtime
找到time_t(0)
的日期,但如果那是2000-01-01T00:00Z
怎么办?1970-01-01T00:00Z
到2000-01-01T00:00Z
之间有多少秒钟?由于闰秒,它肯定不是60的倍数。
gmtime()
来获取该时间戳所编码的可读表示形式,但问题中请求的功能并不满足time()
的要求。 - Tony Delroy1970-01-01T00:00Z
之间的差异(以秒为单位)。没有可执行此操作的方法。 - MSalters由于这是谷歌上的第一个结果,并且还没有C++20的答案,因此以下是如何使用std::chrono进行此操作的:
#include <chrono>
//...
using namespace std::chrono;
int64_t timestamp = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
在 C++ 20 版本之前,system_clock 的时代被视为 Unix 时代是一种事实约定,但它并没有标准化。如果你不使用 C++20,请自行承担风险。
我创建了一个包含更多信息的全局定义:
#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__
的作用将无法实现。这是一个宏。 - xinthose#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>
? - Keith ThompsonWindows使用不同的纪元和时间单位:请参见将Windows Filetime转换为Unix/Linux中的秒
目前我还不知道在Windows上std::time()返回什么 (;-))
#include <chrono>
uint64_t unix_time()
{
return std::chrono::duration_cast<std::chrono::nanoseconds>
(
std::chrono::system_clock::now().time_since_epoch()
).count();
}
std::chrono::seconds
的定义 为duration</*至少35位有符号整数类型*/>
。因此,例如32位int可能不足够。 - Paul