我試圖讓當前年份存儲在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。 –