在UTC / GMT得到一天开始的正确方法是什么?


::tm tm{0, 0, 0, 29, 10, 2022 - 1900, 0, 0};  // 10 for November
auto time_t = ::mktime(&tm);
cout << "milliseconds = " << time_t * 1000 << endl;

以上代码输出1669660200000,相当于2022十一月29日00:00:00。但它是在当地时区。如何获得上述日期的UTC时间?
一个具有线程安全的现代c++17方式将是值得赞赏的。

在您的解决方案中有一个单元挑剔的弱点(除了线程安全问题):tm的成员不能保证按您假设的顺序排列。

tm结构体应至少包含下列成员,按任意顺序:

使用c++ 17,您可以使用这个c++ 20计时预览库。它是免费的,开源的,并且只有头文件。您的程序看起来像:

#include "date/date.h"
#include <chrono>
#include <iostream>
int
main()
{
using namespace std;
using namespace chrono;
using namespace date;
sys_time<milliseconds> tp = sys_days{2022_y/11/29};
cout << "milliseconds = " << tp.time_since_epoch().count() << 'n';
}

输出将是:

milliseconds = 1669680000000

使用这个库的一个好处是它可以很容易地移植到c++ 20。c++ 20版本如下:

#include <chrono>
#include <iostream>
int
main()
{
using namespace std;
using namespace chrono;
sys_time<milliseconds> tp = sys_days{2022y/11/29};
cout << "milliseconds = " << tp.time_since_epoch() << 'n';
}

和输出:

milliseconds = 1669680000000ms
演示:

一种老式的c风格方法是首先获得时区差,并将其与问题中的值相抵消。

static const auto TIMEZONE_OFFSET = [] (const ::time_t seconds)
{ // This method is to be called only once per execution
::tm tmGMT = {}, tmLocal = {}; 
::gmtime_r(&seconds, &tmGMT); // ::gmtime_s() for WINDOWS
::localtime_r(&seconds, &tmLocal);  // ::localtime_s() for WINDOWS
return ::mktime(&tmGMT) - ::mktime(&tmLocal);
}(10000);
::tm tm{0, 0, 0, 29, 10, 2022 - 1900}; // set fields 1 by 1 as the order is not guaranteed
cout << " start of day = " << (::mktime(&tm) - TIMEZONE_OFFSET) << endl;

相关内容

最新更新