Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/141.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 将时间和持续时间转换为日期_C++_Date_Datetime_Boost_Rounding Error - Fatal编程技术网

C++ 将时间和持续时间转换为日期

C++ 将时间和持续时间转换为日期,c++,date,datetime,boost,rounding-error,C++,Date,Datetime,Boost,Rounding Error,我想把a转换成a格式,这是自1899年12月30日以来的天数 DATE date_from_duration(time_duration td) { double days = td.hours()/24.+td.minutes()/(24.*60.)+td.seconds()/(24.*60.*60.); return days; } 该代码几乎可以工作,但有时会出现舍入错误,即持续时间(1007645,15,0)应导致2014-12-12 00:15:00,但实际上是2014-

我想把a转换成a格式,这是自1899年12月30日以来的天数

DATE date_from_duration(time_duration td)
{
   double days = td.hours()/24.+td.minutes()/(24.*60.)+td.seconds()/(24.*60.*60.);
   return days;
}
该代码几乎可以工作,但有时会出现舍入错误,即
持续时间(1007645,15,0)
应导致2014-12-12 00:15:00,但实际上是2014-12-12 00:14:59

使用此方法检查日期,从:


如何有效地纠正这个舍入问题?这取决于你的情况

一般的问题是
1/(24.*60.*60。)
不能精确地表示为二进制浮点(因为86400不是二的幂)。您得到的
日期
非常精确,但会有舍入误差。有时这意味着它是非常多一点,有时是非常少一点,但你真的没有太多可以做,使它更精确;这是你能得到的最完美的结果。你看到秒的差异可以说是你检查中的一个问题,因为你不再看秒——如果你检查
毫秒
,你很可能得到999,使舍入误差看起来不那么极端。这将持续
微秒
,也可能持续
纳秒
,具体取决于
持续时间的分辨率

所以很可能没有什么可做的,因为数据是正确的。但是,如果您不关心毫秒及以上,只希望秒值在来回转换中保持稳定,则实现这一点的最简单方法是添加一个ε值:

DATE date_from_duration(time_duration td)
{
   double days =
       td.hours  () /  24.
     + td.minutes() / (24. * 60.)
     + td.seconds() / (24. * 60. * 60.)
     + 1e-8; // add roughly a millisecond
   return days;
}

这增加了整体舍入误差,但确保误差处于“安全”方向,即,将其转换回
持续时间
将给出相同的
秒()
值,可见的变化将处于
毫秒()
级别。

我可能缺少一些复杂性,但对我来说,这似乎很简单:


我不在乎毫秒,所以添加1e-8是我的解决方案。谢谢为什么要做这些计算,而这正是图书馆的用途?我不明白。我发布了一个简单得多的答案。您可以不使用任何浮点,也不会有舍入和舍入问题:)
DATE date_from_duration(time_duration td)
{
   double days =
       td.hours  () /  24.
     + td.minutes() / (24. * 60.)
     + td.seconds() / (24. * 60. * 60.)
     + 1e-8; // add roughly a millisecond
   return days;
}
#include <boost/date_time/posix_time/posix_time.hpp>
#include <iostream>
using DATE = double;

boost::posix_time::ptime pTime_from_DATE(double date)
{
    static const boost::posix_time::ptime::date_type base_date(1899, boost::gregorian::Dec, 30);
    return boost::posix_time::ptime(
            base_date, 
            boost::posix_time::milliseconds(date * 1000 * 60 * 60 * 24));
}

int main() {
    boost::posix_time::time_duration duration(1007645, 15, 0);

    DATE date = duration.total_milliseconds() / 1000.0 / 60 / 60 / 24;

    std::cout << date << ": " << pTime_from_DATE(date);
}
41985.2: 2014-Dec-12 05:15:00