我试图让当前年份存储在1970年之前的日期使用std::chrono::time_point<std::chrono::system_clock>
,但是我遇到了一个有关从其内容阅读的问题到一个std::tm
结构。localtime_s失败其中gmtime_s成功与日期之前1-1-1970
我首先将time_point
转换为time_t
,之后我读取它的值以得到tm_year
的值。但是,尝试这样做时,代码在使用localtime_s
时失败,但在使用gmtime_s
时成功。这只适用于1-1-1970之前的日期,在此之后的日期使用这两个函数都很好。
下面的代码重现错误。如果使用utc=true
调用terstGmTimeVsLocalTime
,它将起作用,如果使用utc=false
调用它,则不会生成正确的输出。
#include <iomanip>
#include <time.h>
#include <iostream>
void testGmTimeVsLocaltime(const bool& utc) {
// Create time
std::tm timeInfoWrite = std::tm();
timeInfoWrite.tm_year = 1969 - 1900; // Year to parse, here it is 1969
timeInfoWrite.tm_mon = 0;
timeInfoWrite.tm_mday = 1;
timeInfoWrite.tm_hour = 1;
timeInfoWrite.tm_min = 0;
timeInfoWrite.tm_sec = 0;
timeInfoWrite.tm_isdst = -1;
std::chrono::time_point<std::chrono::system_clock> timePoint = std::chrono::system_clock::from_time_t(utc ? _mkgmtime(&timeInfoWrite) : std::mktime(&timeInfoWrite));
// Convert to time_t
std::time_t timeT = std::chrono::system_clock::to_time_t(timePoint);
// Read values
std::tm timeInfoRead;
if (utc) {
gmtime_s(&timeInfoRead, &timeT);
} else {
localtime_s(&timeInfoRead, &timeT);
}
// Output result
std::cout << (timeInfoRead.tm_year + 1900) << '\n';
// Wait for input
std::getchar();
}
int main() {
testGmTimeVsLocaltime(true); // Set to false to show bug
return 0;
}
utc=true
输出1969,如预期的那样。然而,utc=false
输出1899(可能是因为发生错误,tm_year
设置为-1)。
有什么我失踪? The documentation没有具体说明localtime_s
在1-1-1970之前的日期会失败。
我在Windows 10 x64上,如果它有所作为。
MSDN文档建议它会失败:“1970年1月1日午夜前。”请参阅https://msdn.microsoft.com/en-us/library/bf12f0hc.aspx –
@RichardCritten嗯,我看到我一定是使用了一个操作系统特定的实现。没有意识到'localtime_s'不是标准的一部分。 1970年1月1日午夜之前会有另一个功能不会失败吗?或者也许是另一种策略 我想我可以检索UTC和本地时间之间的差异,只需使用'gmtime_s'函数,然后在需要本地时间时将差异添加到结果中,但似乎可以做得更简单。 – Qub1
您链接的文档说_“自__epoch __转换给定的时间”_;时间是实施决定时间开始的时间点。在Windows上有操作系统调用,可以在任何时间工作,但我不知道任何标准的API。 –