创建日期向量时舍入问题

时间:2015-03-04 11:56:16

标签: arrays matlab date floating-accuracy

我想在matlab中创建一个包含日期的向量。为此,我指定了开始时间和停止时间:

WHM01_start = datenum('01-JAN-2005 00:00')
WHM01_stop = datenum('01-SEP-2014 00:00')

然后我用

创建了矢量
WHM01_timevec = WHM01_start:datenum('01-JAN-2014 00:20') - datenum('01-JAN-2014 00:00'):WHM01_stop;
在我想要每次20分钟的时间之后

。不幸的是,在数千个值之后我得到一个舍入误差,导致我

>> datestr(WHM01_timevec(254160))

ans =

31-Aug-2014 23:39:59

而不是预期的,31-Aug-2014 23:40:00
如何更正这些不正确的值?

编辑:我也看到了这个thread,但不幸的是我每个日期都有一个向量,而不是所需的数字。

2 个答案:

答案 0 :(得分:4)

您可以将数字格式的年,月,日,...赋予函数datenum。 Datenum接受其一个或多个参数的向量,如果数字太大(例如,120分钟),datenum知道如何处理它。

因此,通过以20分钟为增量提供分钟向量,您可以避免舍入错误(至少在1秒级别):

WHM01_start = datenum('01-JAN-2005 00:00');
WHM01_stop = datenum('01-SEP-2014 00:00');

time_diff = WHM01_stop - WHM01_start;

WHM01_timevec = test = datenum(2005,01,01,00,[00:20:time_diff*24*60],00);

datestr(WHM01_timevec(254160))

回答你的评论:

您看到舍入错误的原因是您使用两个大数字的差异作为时间增量。大数的差异具有(相对)大的舍入误差。

Matlab时间以(虚构)日期0.0.0000后的天数计算。您的时间增量为1/3小时,或1 /(24 * 3)天。修改原始代码,使其显示为

WHM01_timevec = WHM01_start:1/(24*3):WHM01_stop;

是减少舍入误差的另一种方法,但是对于非常大的时间跨度,第一种解决方案是一种更强大的方法。

答案 1 :(得分:4)

Related answer:使用linspace代替colon operator :

%// given
WHM01_start = datenum('01-JAN-2005 00:00')
WHM01_stop = datenum('01-SEP-2014 00:00')

%// number of elements
n = numel(WHM01_start: datenum('01-JAN-2014 00:20') - ...
                       datenum('01-JAN-2014 00:00') : WHM01_stop);

%// creating vector using linspace
WHM01_timevec = linspace(WHM01_start, WHM01_stop, n);

%// proof
datestr(WHM01_timevec(254160))

ans =

31-Aug-2014 23:40:00

这个解决方案的缺点:确定输出向量的元素数量我使用:创建的原始向量,这可能不是最佳选择。


链接答案的重要引用:

使用linspace可以降低发生这些问题的可能性,但这不是安全措施。