繁体   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