TIME_DURATION转换为DATE [英] Converting time_duration to DATE

查看:396
本文介绍了TIME_DURATION转换为DATE的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想转换一个 TIME_DURATION 日期的格式,这是自1899年以来,12个天数30。

I want to convert a time_duration to a DATE format, which is the number of days since 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;
}

这code差不多的作品,但有时给人舍入误差,科幻的 TIME_DURATION(1007645,15,0)应导致2014-12-12 00:15 :00,但实际上是2014-12-12〇时14分59秒。

This code almost works but gives sometimes rounding errors, f.i the time_duration(1007645, 15, 0) should result in 2014-12-12 00:15:00, but is actually 2014-12-12 00:14:59.

日期的检查是用这种方法做的,从 rel=\"nofollow\">:

The check of DATE is done with this method, stolen from here:

ptime pTime_from_DATE(double date)
{
    using boost::math::modf;

    static const ptime::date_type base_date(1899, Dec, 30);
    static const ptime base_time(base_date, ptime::time_duration_type(0,0,0));

    int dayOffset, hourOffset, minuteOffset, secondOffset;
    double fraction = fabs(modf(date, &dayOffset)) * 24; // fraction = hours
    fraction = modf(fraction, &hourOffset) * 60; // fraction = minutes
    fraction = modf(fraction, &minuteOffset) * 60; // fraction = seconds
    modf(fraction, &secondOffset);
    ptime t(base_time);
    t += ptime::time_duration_type(hourOffset, minuteOffset, secondOffset);
    t += ptime::date_duration_type(dayOffset);
    return t;
}

任何想法如何有效地解决这个问题,四舍五入?

Any ideas how to correct this rounding issue efficiently?

推荐答案

这是一种取决​​于你的情况。

That kind of depends on your circumstances.

的一般问题是, 1 /(24 * 60 * 60)是不完全重新presentable作为二进制浮点(因为86400是不二的幂)。在日期你得到的是非常接近准确的,但会有一个舍入误差。有时,这意味着它不太很少的多,有时很少,但确实不是很多,你可以做,使之更precise;这是完全没有问题,你可以得到。那你看一秒钟的差距可以说是与你检查的问题,在您停止在看秒 - 如果你检查毫秒,你可能得到999,使得舍入误差看起来少了很多极端的。这将继续为微秒和可能纳秒,取决于分辨率 TIME_DURATION

The general problem is that 1 / (24. * 60. * 60.) is not exactly representable as a binary float (because 86400 is not a power of two). The DATE you get is very nearly exact, but there will be a rounding error. Sometimes this means that it is very little more, sometimes very little less, but there's really not a lot you can do to make it more precise; it is as perfectly alright as you can get. That you see a discrepancy of a second is arguably a problem with your check, in that you stop looking at seconds -- if you check the milliseconds, you're likely to get 999, making the rounding error look a lot less extreme. This will continue for microseconds and possibly nanoseconds, depending on the resolution of time_duration.

所以很可能有什么可以做,因为数据是好的。但是,如果你不关心毫秒,超越,只希望秒钟值是在转换稳定来回,以实现最简单的方法是添加一个小量值:

So quite possibly there's nothing to do because the data is alright. If, however, you don't care about milliseconds and beyond and only want the seconds value to be stable in conversions back and forth, the simplest way to achieve that is to add an epsilon value:

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;
}

这增加了整体的舍入误差,但可以确保误差在一个安全的方向,即,将其转换回 TIME_DURATION 将给予同样的秒()值和显着的变化将在毫秒()的水平。

This increases the overall rounding error but ensures that the error is in a "safe" direction, i.e., that converting it back to time_duration will give the same seconds() value and the visible changes will be at the milliseconds() level.

这篇关于TIME_DURATION转换为DATE的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆