簡體   English   中英

在 UTC 中將 windows 上的 tm 轉換為 time_t - _mkgmtime 返回 -1

[英]Converting tm to time_t on windows in UTC - _mkgmtime returning -1

我正在嘗試將 UTC ECMA 日期格式字符串解析為 Windows 上的std::chrono::system_clock::time_point time_point。

我的計划:

  1. 使用scanf將字符串加載到struct tm
  2. 使用_mkgmtime將其轉換為time_t (我為此使用_mkgmtime ,因為它使用 UTC 時間,不像mktime之類的使用本地時間的東西)。
  3. 使用std::chrono::system_clock::from_time_t轉換為time_point

但是,第 2 步總是為我返回 -1,給我第 3 步的虛假值。

tm結構似乎有效,所以我不確定我做錯了什么。

#include <chrono>
#include <iostream>

using namespace std;

int main() {
  string timeStr = "2020-12-01T06:06:48Z";

  struct tm tm = {0};
  float s;
  if (sscanf_s(timeStr.c_str(), "%d-%d-%dT%d:%d:%fZ", &tm.tm_year, &tm.tm_mon,
               &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &s) == 6) {
    tm.tm_sec = static_cast<int>(s);

    time_t t = _mkgmtime(&tm);
    cout << "YEAR: " << tm.tm_year << endl;  // 2020
    cout << "MON:  " << tm.tm_mon << endl;   // 12
    cout << "MDAY: " << tm.tm_mday << endl;  // 1
    cout << "HOUR: " << tm.tm_hour << endl;  // 6
    cout << "MIN:  " << tm.tm_min << endl;   // 6
    cout << "SEC:  " << tm.tm_sec << endl;   // 48
    cout << "TIME: " << t << endl;           // -1

    // TODO once this is solved:
    auto tp = chrono::system_clock::from_time_t(t);
  }
}

編譯器是 MSVC 2019,C++17,x64。 我無法升級到 C++20,否則我會為此使用新的計時工具。

tm結構中,成員tm_year是自 1900 年以來的年數 在 2020 年喂養意味着您實際上是在提供 3920 年。

看起來_mkgmtime討厭那一年。 在我的系統_mkgmtime64似乎也不起作用。 它應該適合 64 位time_t ,但絕對超出 32 位版本的范圍。 我找不到明確的、記錄在案的 3920 被拒絕的原因或 function 放棄的截止點。 確保您有 64 位time_t

但在這種情況下,這些都不重要,因為我們想要 2020 年。添加

tm.tm_year -= 1900;
tm.tm_mon -= 1; // valid range 0 to 11, not 1 to 12

在轉換之前會解決問題。

這是它在 C++20 中的樣子:

#include <chrono>
#include <iostream>
#include <sstream>

int
main()
{
    using namespace std;
    using namespace std::chrono;
    string timeStr = "2020-12-01T06:06:48Z";
    istringstream in{timeStr};
    system_clock::time_point tp;
    in >> parse("%FT%TZ", tp);
    cout << tp << '\n';  // 2020-12-01 06:06:48.000000
}

使用C++20 <chrono>預覽庫,只需添加#include "date/date.h"using namespace date; 它現在適用於 C++11/14/17。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM