Convert decimal dates in loop
14 views (last 30 days)
Show older comments
I need help with converting a decimal date to Day/Month/Year AND MATLAB serial date. (Yes this is the same question I asked in another post. That one diverged from the intended question and was not likely to get answered judging by the comments. I am asking in a simpler manner.)
What I need is a robust method that can take one input and give me two outputs.
Input - decimal date
Output 1 - Day/month/Year
Output 2 - MATLAB date code
Example: Input - 1998.95...(long string of values)
Output 1 - 16/Dec/1998
Output 2 - 730105
I can achieve a loop from Input to output 1, but not to output 2. I can get to output 2 with some fiddling. I need to import the data from loop 1 in to a separate variable, then run a separate loop. This method is not worthwhile as it means I will need to do extra steps and there it can lead to mistakes.
Again, what I need is a loop that works directly. Input to output 1 AND output 2.
I can get to input 2 individually, but not in a loop. With a long list of decimal dates (think well over 5000), it would help to have a single loop that can do it, but this apparently does not exist.
Here is what I have to get me from my input to a Day/Month/Year:
A = xlsread('Example.xlsx');
B = num2cell(A);
[fid,msg] = fopen(sprintf('Example3.txt'),'wt');
assert(fid>=0,msg)
for q = 1:5555
DecDate = B{q,5}; %This is the column with the decimal dates in it.
n = datestr(datenum(DecDate,1,0));
fprintf(fid,'%s\n', n);
%DateString = datestr(datenum(DecDate,1,0)); %This line is optional?
%formatIn = 'dd-mmm-yyyy HH:MM:SS';
%p = datenum(n,formatIn); %This is where the problem is.
%p = datenum(DateString,formatIn); %This line also caused problems.
%fprintf(fid,'%s', ' ');
%fprintf(fid,'%s', p);
end
fclose(fid);
5 Comments
Walter Roberson
on 19 Jul 2018
What difficulty did you have with the code I posted in https://www.mathworks.com/matlabcentral/answers/410636-help-with-converting-decimal-dates-in-a-loop#answer_329398 ?
Answers (2)
Steven Lord
on 19 Jul 2018
I assume the integer part of x is the year, and the fractional part is the fraction of the way through that year representing the date and time you want? If so use datetime.
x = 1998.95918367347;
dt = datetime(floor(x), 1, 1) + years(x-floor(x))
[Y, M, D] = ymd(dt)
n = datenum(dt)
I think x corresponds to a time on December 17th not December 16th, since you'd want x = 1998 to correspond to midnight on January 1st not January 0th.
Unless you have a strong need to work with the serial date numbers, however, I'd strongly recommend working with the datetime array instead. There are many operations implemented for datetime that you'd have to create yourself if you work with the serial date numbers or that are more difficult to perform with the serial date numbers.
1 Comment
Stephen23
on 14 Sep 2022
Edited: Stephen23
on 14 Sep 2022
Note that by using YEARS this approach incorrectly assumes that a year has exactly
format long G
365.2425 * 24 % hours
whereas in fact the length of a calendar year is a) never equal to this value and b) depends on the year. The bug in this approach can be clearly demonstrated at the very end of a non-leap year, where this incorrect calculation returns a date in the following year (due to the flawed usage of YEARS):
x = 2021.9999999; % well within floating point precision
dt = datetime(floor(x), 1, 1) + years(x-floor(x)) % oops, we jumped into the future!
To get the correct year length for any specific year (required for that fraction), something like CALYEARS or DATESHIFT or two DATETIMES or similar would be required:
Z = datetime(floor(x),1,1);
Z = Z + mod(x,1).*((Z+calyears(1))-Z) % much better!
Y = datetime(floor(x)+[0;1],1,1);
Y = Y(1) + mod(x,1).*diff(Y) % this also works!
etc.etc.
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!