如何从 std::tm 转换为 Windows::Foundation::DateTime

How to convert from std::tm to Windows::Foundation::DateTime

我正在尝试在 Windows 运行时组件中将 std::tm 转换为 Windows::Foundation::DateTime

Windows::Foundation::DateTime中唯一的属性是UniversalTime,定义为:

A 64-bit signed integer represents a point in time as the number of 100-nanosecond interval prior to or after midnight on January 1, 1601 (according to Gregorian Calendar)

有没有办法在 std 中获取此值?还是有一种标准的方法来进行转换?

您可以使用 mktime 将时间转换为 unix, 然后添加幻数 116444736000000000ULL:

    /* shift is difference between 1970-Jan-01 & 1601-Jan-01
    * in 100-nanosecond intervals */
    const uint64_t shift = 116444736000000000ULL; // (27111902 << 32) + 3577643008

来自 boost/date_time/filetime_functions.hpp

这是另一种派生此常量的方法,但需要此 date library 序列化两个公历日期:

#include "date.h"

int
main()
{
    using namespace std::chrono;
    using namespace date;
    using namespace std;
    using wticks = ratio_multiply<nano, ratio<100>>;
    constexpr duration<int64_t, wticks> t =
                          sys_days{jan/1/1970} - sys_days{jan/1/1601};
    static_assert(t.count() == 116444736000000000, "");
}

这需要C++14在编译时完成。在 C++11 中,这可以在 运行 时间完成(即你不能将 t 声明为 constexpr 或在 C++11 中的 static_assert 中使用它). date library 已移植到 VS-2015,但 constexpr 目前在该平台上被禁用。

更新

这是将本地 tm 转换为自 1601 年 1 月 1 日以来以 100 纳秒为单位的数字的代码。要计算出计算机的本地时区,需要此 timezone library

#include "date.h"
#include "tz.h"
#include <iostream>
#include <thread>

int
main()
{
    using namespace std::chrono;
    using namespace date;
    using namespace std;

    // Concurrently initialize timezone database (as an optimization)
    thread{get_tzdb}.detach();

    // get an example local tm
    auto now = time(nullptr);
    struct tm tm = *localtime(&now);

    // convert tm into a local time_point
    auto local_tp = local_days{year{tm.tm_year+1900}/(tm.tm_mon+1)/tm.tm_mday}
        + hours{tm.tm_hour} + minutes{tm.tm_min} + seconds{tm.tm_sec};

    // convert local time_point to UTC time_point
    auto tp = current_zone()->to_sys(local_tp);

    // Create handy types for dealing with 100-nanosecond units
    using wperiod = ratio_multiply<nano, ratio<100>>;
    using wticks  = duration<int64_t, wperiod>;

    // Get number of 100-nanosecond intervals since Jan 1, 1601 00:00:00 UTC
    auto t = wticks{tp - sys_days{jan/1/1601}};
    cout << t.count() << '\n';
}

这只是为我输出:

130925235970000000