Dutation type doesn’t preserve seconds accuracy
I’ve been working on some time conversion routines and ran into an issue I didn’t expect. Basically, the duration type doesn’t preserve seconds accuracy. This is caused by the fact that the duration type stores the duration as a single variable called millis (i.e., milliseconds) instead of separate d,h,m,ms or h,m,ms. Why this would be coded in that way does not make any sense to me. E.g., because of this you can get issues such as this:
format longg
dt1 = datetime(2000,1,1,0,0,1.2345678912345);
disp(dt1.Second)
dt2 = datetime(2000,1,1);
[~,~,s] = hms(dt1-dt2)
All well and good, the seconds is represented to full precision in the datetime variable, and the precision of the seconds difference is preserved in the subtraction because the datetimes are close to one another. But if they are not:
dt3 = datetime(1900,1,1);
[~,~,s] = hms(dt1-dt3)
You suddenly get a different result because the difference got mashed into a single millis variable and that large days value caused precision loss in the seconds. And simply constructing a duration type from scratch doesn’t solve anything either because of the internal duration storage as a single millis variable. E.g.,
[~,~,s] = hms(duration(0,0,1.2345678912345))
[~,~,s] = hms(duration(1e6,0,1.2345678912345))
I know, I know … "You shouldn’t depend on this level of accuracy in floating point calculations" etc. But that’s not the point. The point is as long as you have a datetime type that stores individual d,h,m,s properties, then IMHO the duration type should follow suit and preserve accuracy in calculations as much as possible to match it. If the duration type stored the data internally as d,h,m,s (or ms or ns) and took care when doing the internal arithmetic, the above differences could be avoided. In fact, since the millis is a private internal variable, I think TMW could still do this in future versions of MATLAB without breaking any user code since there shouldn’t be any user code that accesses the millis property. Any chance of this, TMW?
And speaking of the datetime type, IMHO the internal variable should have been millis or nanos instead of seconds. That way standard Terrestrial Time epochs such as J2000 (January 1, 2000, 11:58:55.816 UTC) etc. could be represented exactly internally. But since datetime y,m,d,h,m,s properties are public this unfortunately can’t be changed now.I’ve been working on some time conversion routines and ran into an issue I didn’t expect. Basically, the duration type doesn’t preserve seconds accuracy. This is caused by the fact that the duration type stores the duration as a single variable called millis (i.e., milliseconds) instead of separate d,h,m,ms or h,m,ms. Why this would be coded in that way does not make any sense to me. E.g., because of this you can get issues such as this:
format longg
dt1 = datetime(2000,1,1,0,0,1.2345678912345);
disp(dt1.Second)
dt2 = datetime(2000,1,1);
[~,~,s] = hms(dt1-dt2)
All well and good, the seconds is represented to full precision in the datetime variable, and the precision of the seconds difference is preserved in the subtraction because the datetimes are close to one another. But if they are not:
dt3 = datetime(1900,1,1);
[~,~,s] = hms(dt1-dt3)
You suddenly get a different result because the difference got mashed into a single millis variable and that large days value caused precision loss in the seconds. And simply constructing a duration type from scratch doesn’t solve anything either because of the internal duration storage as a single millis variable. E.g.,
[~,~,s] = hms(duration(0,0,1.2345678912345))
[~,~,s] = hms(duration(1e6,0,1.2345678912345))
I know, I know … "You shouldn’t depend on this level of accuracy in floating point calculations" etc. But that’s not the point. The point is as long as you have a datetime type that stores individual d,h,m,s properties, then IMHO the duration type should follow suit and preserve accuracy in calculations as much as possible to match it. If the duration type stored the data internally as d,h,m,s (or ms or ns) and took care when doing the internal arithmetic, the above differences could be avoided. In fact, since the millis is a private internal variable, I think TMW could still do this in future versions of MATLAB without breaking any user code since there shouldn’t be any user code that accesses the millis property. Any chance of this, TMW?
And speaking of the datetime type, IMHO the internal variable should have been millis or nanos instead of seconds. That way standard Terrestrial Time epochs such as J2000 (January 1, 2000, 11:58:55.816 UTC) etc. could be represented exactly internally. But since datetime y,m,d,h,m,s properties are public this unfortunately can’t be changed now. I’ve been working on some time conversion routines and ran into an issue I didn’t expect. Basically, the duration type doesn’t preserve seconds accuracy. This is caused by the fact that the duration type stores the duration as a single variable called millis (i.e., milliseconds) instead of separate d,h,m,ms or h,m,ms. Why this would be coded in that way does not make any sense to me. E.g., because of this you can get issues such as this:
format longg
dt1 = datetime(2000,1,1,0,0,1.2345678912345);
disp(dt1.Second)
dt2 = datetime(2000,1,1);
[~,~,s] = hms(dt1-dt2)
All well and good, the seconds is represented to full precision in the datetime variable, and the precision of the seconds difference is preserved in the subtraction because the datetimes are close to one another. But if they are not:
dt3 = datetime(1900,1,1);
[~,~,s] = hms(dt1-dt3)
You suddenly get a different result because the difference got mashed into a single millis variable and that large days value caused precision loss in the seconds. And simply constructing a duration type from scratch doesn’t solve anything either because of the internal duration storage as a single millis variable. E.g.,
[~,~,s] = hms(duration(0,0,1.2345678912345))
[~,~,s] = hms(duration(1e6,0,1.2345678912345))
I know, I know … "You shouldn’t depend on this level of accuracy in floating point calculations" etc. But that’s not the point. The point is as long as you have a datetime type that stores individual d,h,m,s properties, then IMHO the duration type should follow suit and preserve accuracy in calculations as much as possible to match it. If the duration type stored the data internally as d,h,m,s (or ms or ns) and took care when doing the internal arithmetic, the above differences could be avoided. In fact, since the millis is a private internal variable, I think TMW could still do this in future versions of MATLAB without breaking any user code since there shouldn’t be any user code that accesses the millis property. Any chance of this, TMW?
And speaking of the datetime type, IMHO the internal variable should have been millis or nanos instead of seconds. That way standard Terrestrial Time epochs such as J2000 (January 1, 2000, 11:58:55.816 UTC) etc. could be represented exactly internally. But since datetime y,m,d,h,m,s properties are public this unfortunately can’t be changed now. duration, datetime, seconds MATLAB Answers — New Questions