簡體   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