如何获取自C++纪元 (MSVS) 以来的本地当前时间(以秒为单位)
How to get the local current time in seconds since epoch in C++ (MSVS)?
我需要自纪元以来的本地(带时区偏移量(当前时间(以秒为单位(。下面的代码看起来有点笨拙,因为它创建了一个多余的中间临时结构 tm。为什么我必须获取time_t然后将其转换为 tm 才能返回time_t?有没有更好的方法?
time_t ct = time(0);
tm lct = tm();
localtime_s(&lct, &ct);
ct = _mkgmtime(&lct);
如果您想在可移植 C 中获取本地时间(应用时区和 DST(,那么是的,这通常是一个两步过程:从您的时代开始,首先调用localtime
,然后对生成的细分struct tm
执行一些操作。 (通常我接下来要做的是打电话给strftime
。
还可以调用 ctime
直接获取本地时间字符串。
涉及许多不同的函数调用的原因是,不幸的是,有几种不同的时间格式在使用中。 (原因是日期和时间很复杂! 您可以将时间表示为自 1970 年以来的秒。 您可以将其表示为struct tm
。 您可以将其表示为字符串(采用几种亿万种格式之一(。 在Unix和Linux中,您可以将其表示为struct timeval
或struct timespec
。
但是,正如您所发现的,有一件事没有一种简单或标准的方法可以做到,那就是将本地时间作为自 1970 年以来的秒数。 但原因是它不是一个非常有用的表示。 通常,您可能希望对日期/时间值执行两件事:(1( 对其执行计算或 (2( 向用户显示它。 如果要向用户显示它,则可能希望以本地时间显示它,因此有很多方法可以以所需的任何格式转换为人类可读格式的本地时间。 (正如我所说,通常的方法是打电话给localtime
,然后strftime
。 但是如果你想执行计算,实际上唯一的方法是在UTC中使用自1970年以来的秒,因为这会使所有其他棘手的问题消失。 一个月有多少天? 是闰年吗? 我们在哪个时区? 夏令时是否有效?
但是,如果您尝试将当地时间表示为自 1970 年以来的秒数,您可能会在撒谎。 例如,现在,时间是1460383736,即 14:08:56 UTC。 我坐的地方是10:08:56 EDT(美国东部时间,实际上是DST(。 所以我想我可以说这是自当地时间1970年以来的1460369336秒。 但是,再说一遍,1460369336秒前不是1970年1月1日的午夜,实际上是1969年12月31日的晚上11点。 它相差了一个小时,原因是 DST 在 1970 年 1 月 1 日未生效。
所以,最重要的是,我鼓励你重新思考你处理本地时间的方式,因为虽然可以计算这个"自 1970 年以来的秒数作为本地时间"值,但这是一件奇怪的事情,它可能会导致你遇到各种问题,这些问题比你使用更直接的方案更难解决。
但是,如果您真的愿意,您可以通过以下两种方法确定 UTC 和本地时间之间的偏移量,而无需调用 gmtime
或 _mkgmtime
:
- 调用
localtime
,并查看tm_gmtoff
字段。 (遗憾的是,此字段是非标准的,并非在所有系统上都存在。 - 调用过时的
ftime
函数,查看struct timeb
的timezone
字段。 (这里有几个陷阱:不仅ftime
过时和非标准,而且timezone
场以分钟为单位,格林威治以西的区域是积极的,而tm_gmtoff
是负面的。
但是,无论如何,这些或多或少会直接为您提供自 1970 年以来的 UTC 秒值中添加或减去的数字,以获得自 1970 年以来的"本地"秒数。
这是一种使用 C++11/14 <chrono>
库和这个免费的开源时区库进行此计算的方法,用于转换为本地时间。
#include "tz.h"
#include <iostream>
int
main()
{
using namespace date;
using namespace std;
using namespace std::chrono;
auto now = floor<seconds>(system_clock::now());
auto s = current_zone()->to_local(now) - local_days{1970_y/jan/1};
cout << s.count() << 'n';
}
您首先通过 current_zone()
发现您当前的 IANA 时区。 然后你用system_clock::now()
获取当前时间,并将其截断为seconds
。 接下来,您可以将其转换为本地时间,然后从所需的任何纪元中减去结果(在本例中为 1970-01-01(。
结果的类型为 std::chrono::seconds
。
话虽如此,我对这样做持同样的保留意见,正如史蒂夫峰会的回答中所描述的那样。
如果您决定将时间戳表示为字符串,这也很容易完成:
auto now = make_zoned(current_zone(), floor<seconds>(system_clock::now()));
auto str = format("%F %T %z", now);
str
有类型 std::string
. 这只是为我输出:
2016-04-11 11:42:50 -0400
这是我当前的本地时间(截断为秒(,以及我当前的本地 UTC 偏移量。
如果将来您认为秒精度太粗,则只需更改一行即可轻松地将上述代码更改为任何其他精度:
floor<milliseconds>(system_clock::now());
现在str
的内容如下所示:
2016-04-11 11:42:50.368 -0400
- 以天C++为单位的两个时间戳之间的差异
- 如何以毫秒为单位获取开始时间和 now() 之间的毫秒差异(以 C++为单位?
- 如何找到两个日期之间的时间差异(以秒和纳秒为单位)?
- 测量精确的时间,单位为纳秒C++
- 如何在python和C++中以毫秒为单位打印相同的时间
- C++ 旧时间到现在的时间(以小时为单位)
- 如何找到纪元时间戳和 std::chrono::system_clock::now 之间的时差(以毫秒为单位)
- 仅使用C++中的标准库获取以毫秒为单位的当前日期和时间
- 以秒为单位将时间从纪元转换为一年中的某一天?
- 如何使用闰秒以微秒为单位获取 UTC 时间
- 测量 std::系统的实际执行时间(以 C++ 为单位)
- 优先级队列的时间复杂度(以C++为单位)
- C++以微秒为单位解析日期/时间
- 以C++为单位的聚合代码块的墙时间
- 使用 c++ 获取两个日期与时间字符串之间的差异(以秒为单位)
- 如何在跨平台C++中以毫秒为单位获得系统启动/启动时间(它应该在Windows / IOS / Android / MA
- 以 ns3 为单位计算数据包接收时间
- 如何在C++中以毫秒为单位获取今天的 UTC 午夜时间?
- 计算以毫秒为单位的分类算法对整数阵列排序的时间
- 如何以毫秒为单位获得当前时间