簡體   English   中英

在C ++中將日期/時間(作為Double)轉換為struct * tm

[英]Convert Date/Time (as Double) to struct* tm in C++

我從C#(DateTime.ToOADate()獲取一個日期/時間作為雙倍值,這是一個OLE日期時間)。 它包含從1899年12月31日開始的通過天數,該分數是當天通過的部分。 乘以86400,我得到了秒數,最后是當天的時間。

然而,獲取日期更難。 除了UNIX時間涵蓋的日期(1970/01/01至2038/01/19)之外,我仍然沒有解決方案。 在此期間,mktime()可用於將傳遞的天數轉換為日期時間。

double OleDateTimeValue = 28170.654351851852; // 14.02.1977 15:42:16
struct tm * timeinfo;
int passedDays = (int)OLEDateTimeValue;

// between 1.1.1970 and 18.1.2038
if((passedDays >= 25569) && (passedDays <= 50423)) 
{
    timeinfo->tm_year = 70; //1970
    timeinfo->tm_mon = 0;
    timeinfo->tm_mday = 1 + (passedDays - 25569);
    mktime(timeinfo);
}    
else // date outside the UNIX date/time
{
}

現在,mktime()格式化tm結構以使其表示請求的日期,或者如果值超出給定日期則返回-1。

是否有通用的方法來進行計算? 不幸的是我不能使用MFC,必須使用Visual C ++ 6.0。

謝謝你,馬庫斯

我相信您可以使用VariantTimeToSystemTime函數轉換為SYSTEMTIME。

我喜歡約會轉換 - 他們做了這么好的拼圖!

這里有一些代碼適用於1900-03-01到2100-02-28的日期。 它不能超越這些界限的原因是1900年和2100年不是閏年。 這已針對微軟的COleDateTime進行了測試,並且每天都在該范圍內進行匹配。

int leapDays = (int)((OleDateTimeValue + 1400) / 1461);
timeinfo->tm_year = (int)((OleDateTimeValue - leapDays - 1) / 365);
int janFirst = timeinfo->tm_year * 365 + (int)((timeinfo->tm_year + 7) / 4);
int wholeDays = (int)OleDateTimeValue - janFirst;
if (timeinfo->tm_year % 4 != 0 && wholeDays > 58)
    ++wholeDays;
static int firstOfMonth[12] = { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 };
timeinfo->tm_mon = std::upper_bound(&firstOfMonth[0], &firstOfMonth[12], wholeDays) - &firstOfMonth[0];
timeinfo->tm_mday = wholeDays - firstOfMonth[timeinfo->tm_mon - 1] + 1;

時間部分的轉換是微不足道的,我把它作為練習留給讀者。

轉換為time_t應該很容易(乘以86400並添加常量偏移),然后您可以使用localtime函數。 但是你仍然會受限於UNIX時間范圍。 如果你真的需要超出這個范圍,那么villintehaspam的答案,以及復制所有單個字段,看起來就像是要走的路。

暫無
暫無

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

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