繁体   English   中英

如何将“struct tm”(VTYPE_TM) 转换为 DATE(double) - 原生 API?

[英]How to Convert “struct tm” (VTYPE_TM) to DATE(double) - Native API?

我正在使用本机 API技术在本机 C++(Visual Studio 2013 版)中编写一个小型 DLL。

从我的 DLL 内部的外部程序中,我得到日期(没有时间:只有日、月、年)作为VTYPE_TM类型的变量(这是"struct tm" )。

if (paParams[0].vt == VTYPE_TM) 
 double dateFrom = (double)paParams[0].tmVal ; // convert error - but how ?

接下来,我需要将包含在tm结构中的这个日期转换为DATE(double)类型。

有关DATE(double)的更多信息可以在这里找到 - 在在线计算器https://planetcalc.com/7027/中。

现在是实际问题和我的问题:如何将"struct tm"转换为DATE(double)

据我了解,我们需要编写一个 function 将每个字段值从 tm 结构转换为所需的双精度。 但是没有现成的解决方案吗? 也许我需要使用一些中间类型,但我不知道是哪一种。

你能告诉我如何实现这个吗?

铁杆 C ++ 编程大师的问题!

这可以使用 C++20 <chrono>轻松完成。 不幸的是,这部分 C++20 尚未发布,但供应商正忙于实施它。

幸运的是,对于 C++20 的这一部分,存在一个免费的、开源的、仅包含标头的预览版,它适用于 C++11/14/17。 此外,预览版有一个示例页面,其中已经解决了这个问题作为示例。

这是转换为仅使用double类型来回转换的示例,包括您链接到的文档页面中的所有测试用例。

#include "date/date.h"
#include <ctime>
#include <iostream>

template <class D>
date::sys_time<D>
to_sys_time(double dt)
{
    using namespace date;
    using namespace std::chrono;
    using fdays = duration<double, days::period>;
    using ftime = time_point<system_clock, fdays>;
    auto ft = ftime{fdays{dt}};
    if (ft < ftime{})
    {
        auto d = time_point_cast<days>(ft);
        auto t = d - ft;
        ft = d + t;
    }
    ft -= sys_days{1970_y/January/1} - sys_days{1899_y/December/30};
    return round<D>(ft);
}

template <class D>
double
to_double(date::sys_time<D> tp)
{
    using namespace date;
    using namespace std::chrono;
    using fdays = duration<double, days::period>;
    using ftime = time_point<system_clock, fdays>;
    auto ft = ftime{tp} + (sys_days{1970_y/January/1} - sys_days{1899_y/December/30});
    if (ft >= ftime{})
        return ft.time_since_epoch().count();
    auto d = floor<days>(ft);
    auto t = d - ft;
    return (d + t).time_since_epoch().count();
}

void
test(double d)
{
    using namespace std;
    using namespace std::chrono;
    using namespace date;

    auto t = to_sys_time<seconds>(d);
    auto d2 = to_double(t);
    cout << d << " is " << t << " which is " << d2 << '\n';
}

int
main()
{
    using namespace date;
    using namespace std;
    using namespace std::chrono;
    test(-1.25);
    test(-1.3);
    test(-0.5);
    test(0.5);

    year_month_day today = floor<days>(system_clock::now());

    std::tm tm{};
    tm.tm_year = int{today.year()} - 1900;
    tm.tm_mon = unsigned{today.month()} - 1;
    tm.tm_mday = unsigned{today.day()};

    sys_days sd = year{tm.tm_year + 1900}/(tm.tm_mon + 1)/tm.tm_mday;
    cout << "Today " << today << " is " << to_double(sd) << '\n';
}

这当前输出:

-1.25 is 1899-12-29 06:00:00 which is -1.25
-1.3 is 1899-12-29 07:12:00 which is -1.3
-0.5 is 1899-12-30 12:00:00 which is 0.5
0.5 is 1899-12-30 12:00:00 which is 0.5
Today 2021-01-30 is 44226

前四行只是确认转换函数根据您的文档产生正确的值。

最后,当前日期(UTC)从system_clock::now()获得,转换为std::tm ,然后转换回天精度chrono::time_point (基于system_clock )。 然后将此time_point输入to_double以将其转换为 double,目前结果为 44226。

考虑到文档最后一段中描述的这种格式的奇异历史,这些转换函数是不必要的复杂。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM