[英]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.