When converting datenum to datetime, why does my datetime seem to be off by 1 second?
10 views (last 30 days)
Show older comments
MathWorks Support Team
on 16 Oct 2014
Edited: MathWorks Support Team
on 25 Jul 2016
Before R2014b I used serial date numbers to represent date and time in MATLAB. In R2014b I can use datetime arrays, but when I convert serial date numbers to datetimes, I find that there seems to be a difference of one second between the datetimes and the serial date numbers.
For instance:
>> myDateNum = datenum(2014, 09, 01, 10, 0, 0);
>> datetime(myDateNum, 'ConvertFrom', 'datenum')
ans =
01-Sep-2014 09:59:59
>> datestr(myDateNum)
ans =
01-Sep-2014 10:00:00
Accepted Answer
MathWorks Support Team
on 25 Jul 2016
This is not a bug in MATLAB's functions for "datetime", "datenum" or "datestr" in R2014b, instead this result is caused by precision limitations of serial date numbers. Serial date numbers contain a number of days, using double precision floating point values. However, 1 hour, 1 minute, and 1 second, i.e. the day fraction 1/24, 1/3600, and 1/86400 cannot be represented exactly in double precision. Therefore, in general, time of day in a serial date number is subject to round-off error. For example, 10 am in the example cannot be represented exactly by a serial date number:
>> format long
>> myDateNum
myDateNum =
7.358434166666666e+05
>> 24*(myDateNum - round(myDateNum))
ans =
9.999999999068677
As you can see, the hour-part of this serial date number is slightly less than 10. Datetime values have a higher precision, therefore when you convert a datenum value that represents 10 am, it becomes a datetime value just before 10 am. Because the datetime display does not round up, it may seem that the datetime is off by a full second. This is however not the case as can be seen by changing the format of the datetime value:
>> myDateTime = datetime(myDateNum, 'ConvertFrom', 'datenum')
myDateTime =
01-Sep-2014 09:59:59
>> myDateTime.Format = 'dd-MMM-uuuu HH:mm:ss.SSSSS'
myDateTime =
01-Sep-2014 09:59:59.99999
The difference is indeed in the order of the precision of the serial date number value:
>> eps(myDateNum)*24*3600
ans =
1.005828380584717e-05
After converting a datenum to a datetime, you can round the datetime to an exact whole number of hours, minutes or seconds using the "dateshift" function:
>> dateshift(myDateTime, 'start', 'second', 'nearest')
ans =
01-Sep-2014 10:00:00.00000
Or since datenum is basically a double, you could use "eps" function to avoid round off error:
>> myDateNum = datenum(2014, 09, 01, 10, 0, 0)
myDateNum =
7.3584e+05
>> datetime(myDateNum + eps, 'ConvertFrom', 'datenum')
ans =
01-Sep-2014 10:00:00
0 Comments
More Answers (0)
See Also
Categories
Find more on Dates and Time in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!