Datenum Generating different numbers for same time difference

I have following two date time data points, and I am taking difference of them :
diff_55mins2=abs(datenum('01-04-2017 07:00:00','dd-mm-yyyy HH:MM:SS')-datenum('01-04-2017 07:55:00','dd-mm-yyyy HH:MM:SS'))
diff_55mins1=abs(datenum('01-04-2017 05:00:00','dd-mm-yyyy HH:MM:SS')-datenum('01-04-2017 05:55:00','dd-mm-yyyy HH:MM:SS'))
If you see, both the above code lines are trying to find difference between two date time stamp. The difference is 55 minutes for the both, however after conversion using datenum, there is difference in the numbers as following:
diff_55mins2 =
0.038194444496185
diff_55mins1 =
0.038194444379769
Why there is such difference? They are essentially corresponding to 5 minutes difference in time. Can anyone please explain it.
Thankyou in advance!

 Réponse acceptée

dpb
dpb le 27 Avr 2018
Modifié(e) : dpb le 27 Avr 2018
FP roundoff; datenum just uses a double for the time serial value; the integer portion is days and the fractional part the fractional portion of the day in seconds. It is susceptible to all the vagaries of fp arithmetic....
>> dn2=abs(datenum('01-04-2017 07:00:00','dd-mm-yyyy HH:MM:SS')-datenum('01-04-2017 07:55:00','dd-mm-yyyy HH:MM:SS'))
dn2 =
0.0382
>> dn1=abs(datenum('01-04-2017 05:00:00','dd-mm-yyyy HH:MM:SS')-datenum('01-04-2017 05:55:00','dd-mm-yyyy HH:MM:SS'))
dn1 =
0.0382
>> dn2-dn1
ans =
1.1642e-10
>> ans*24*60*60
ans =
1.0058e-05
>>
So the difference between the two values isn't zero but is about 10 usec or in absolute terms
>> dn=datenum('01-04-2017 05:00:00','dd-mm-yyyy HH:MM:SS')
dn =
7.3679e+05
>> eps(dn)
ans =
1.1642e-10
or the closest can get to the difference in floating point for the size of the variable; iow, a double just can't be any more precise than the result obtained.
To see how close in minutes,
>> format longg
>> dn2*24*60
ans =
55.0000000745058
>> dn1*24*60
ans =
54.9999999068677
>>
Use the new-fangled datetime class instead; it's implemented as an object and has much more precision...
>> fmtDT='dd-MM-yyyy HH:mm:ss'; % a little shorthand; the formatting is different, too...
>> dt1=abs(datetime('01-04-2017 05:00:00','inputformat',fmtDT)-datetime('01-04-2017 05:55:00','inputformat',fmtDT))
dt1 =
duration
00:55:00
>> dt2=abs(datetime('01-04-2017 07:00:00','inputformat',fmtDT)-datetime('01-04-2017 07:55:00','inputformat',fmtDT))
dt2 =
duration
00:55:00
>> dt1==dt2
ans =
logical
1
>>
and the two are identical.
There are many other enhancements with datetime as well that for almost everything now they are the preferred way to handle time.

6 commentaires

Only "almost everything"? Is there a particular operation or application for which you think datenum / datestr / datevec should be preferred over datetime?
dpb
dpb le 27 Avr 2018
Modifié(e) : dpb le 27 Avr 2018
Keeps getting expanded version to version; not all plotting functions yet had their datetime aware versions in R2016b; haven't yet checked for R2017b.
Peter Perkins and I discussed a rather unique problem a couple weeks or so ago raised in Answers that needed an "anchored duration" -- a duration or interval time with a specific date origin which doesn't exist as a separate class/type/object. In the end to generate the desired plot datenum/datetick did turn out more suitable to the task in my view; Peter's workaround entailed writing ticklabels manually that I thought more complex than datetick for the specific case even given the warts therein.
It's border cases for the most part, yes; I'll have to look at some of the other specialty plots again; there have been a couple releases since I ran into many of the problems -- early on, even if were datetime aware, to make changes to axis limits one had to do that in datenum space because the time axis ruler object wasn't yet datetime aware; only the top-level interface. That is no longer the case; there have been some cases I've run across that the higher-level specialty routines weren't yet converted; as noted will have to go back and try to recall which those were, specifically.
ADDENDUM
Actually, what I'd say as general advice is to use datetime first until one does run into one of these edge cases; for most users there will probably not be an issue but as continue to stretch the boundaries as is inevitable there will continue to be uncovered areas that haven't yet gotten fully integrated with the new class.
Okay, that's good feedback, thanks.
I just checked a couple of the cases I was sure I remembered it's now been longer than would have thought (how time flies! :( ) but in R2014b even semilogy didn't make the release, by R2016b both it and bar had as being a couple I do recall as running into once...I was stuck until just this year w/ 32-bit OS/machine so hadn't updated then so for a spell I was lagging pretty badly as rapidly as the new classes were being introduced and fleshed out.
I'll try to make comments going forward more reflective of current state rather than what I tend to remember. :)
Thank you again! Also, etime helps to find the time difference. It is more precise than converting it using datenum.
dpb
dpb le 28 Avr 2018
Modifié(e) : dpb le 28 Avr 2018
Yes, but requires the intermediary of converting to datevec to get there; I'd not recommend it over datetime for new application. If the perceived problem was the duration looking like a time for the above example
>> dt1
dt1 =
duration
00:55:00
>> seconds(dt1)
ans =
3300
>> minutes(dt1)
ans =
55
>> hours(dt1)
ans =
0.916666666666667
>>
to get the values as double of given granularity as desired and there's also flexibility in how to display...
>> dt1.Format='s'
dt1 =
duration
3300 sec
>>

Connectez-vous pour commenter.

Plus de réponses (0)

Catégories

Tags

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by