Decimail Years date to JulianDate
4 views (last 30 days)
Show older comments
Ali Guvenaltin
on 25 Feb 2022
Commented: Peter Perkins
on 3 Mar 2022
Hi Everyone,
I have a column dates like "2008.73907, 2008.74180, 2008.74453, 2008.74727"
Is that possible convert them to Julian Dates? (like 1 January 2000 = 2000.0 = 2451545 )
One more example: 2009.0021 will be 2454832.
Thanks in advance
9 Comments
Stephen23
on 27 Feb 2022
Edited: Stephen23
on 27 Feb 2022
@Ali Guvenaltin: please upload your original data by clicking the paperclip button. The main reason for this is to provide us with the data at its full precision, whereas what you are showing here is presumably limited to four fractional digits.
You do not need to provide us with all of your data, just a range of cases that are representative of your data. Also show us the expected output for the uploaded data.
Accepted Answer
Star Strider
on 27 Feb 2022
Edited: Star Strider
on 27 Feb 2022
Try this —
format long g
T1 = readtable('https://www.mathworks.com/matlabcentral/answers/uploaded_files/908805/exp.txt', 'VariableNamingRule','preserve')
JD = T1.('__MJD') + 2400000.5; % Julian Date
LRP = [T1.('yyyy.yyyy') ones(size(T1,1),1)] \ JD % Linear Regression Parameters
Convert = [T1.('yyyy.yyyy') ones(size(T1,1),1)] * LRP; % Result Is In 'juliandate' Format
Compare = [JD Convert]
DT1 = datetime(Convert,'ConvertFrom','juliandate', 'Format','yyMMMdd') % Original Result
DT2 = datetime(round(Convert,1),'ConvertFrom','juliandate', 'Format','yyMMMdd') % Rounded Result
The ‘LRP’ (Linear Regression Parameters) vector has the slope as the number of days in the year as the first element, and some sort of offset as the second element.
The ‘DT’ result does not necessarily need to be the same as in the first column. See the documentation section on Format for details.
EDIT — (27 Feb 2022 at 21:28)
Corrected typographical errors.
.
2 Comments
More Answers (1)
Peter Perkins
on 2 Mar 2022
Edited: Peter Perkins
on 2 Mar 2022
Maybe I'm missing something. The file contains year and fractional year. Isn't this just
>> T1 = readtable('https://www.mathworks.com/matlabcentral/answers/uploaded_files/908805/exp.txt', 'VariableNamingRule','preserve');
>> T1.Year = floor(T1.("yyyy.yyyy"));
>> T1.FracYear = T1.("yyyy.yyyy") - T1.Year
T1 =
283×5 table
YYMMMDD yyyy.yyyy __MJD Year FracYear
___________ _________ _____ ____ ___________________
{'12JAN01'} 2012 55927 2012 0
{'12JAN02'} 2012.0027 55928 2012 0.00270000000000437
{'12JAN03'} 2012.0055 55929 2012 0.00549999999998363
[snip]
{'12NOV05'} 2012.846 56236 2012 0.846000000000004
{'12NOV06'} 2012.8487 56237 2012 0.848700000000008
{'12NOV07'} 2012.8515 56238 2012 0.851499999999987
>> T1.YearLength = caldays(caldiff(datetime([T1.Year T1.Year+1],1,1),'days',2));
>> T1.JD = floor(juliandate(datetime(T1.Year,1,1),'mjd') + T1.FracYear.*T1.YearLength) + 2400000.5
T1 =
283×7 table
YYMMMDD yyyy.yyyy __MJD Year FracYear YearLength JD
___________ _________ _____ ____ ___________________ __________ _________
{'12JAN01'} 2012 55927 2012 0 366 2455927.5
{'12JAN02'} 2012.0027 55928 2012 0.00270000000000437 366 2455927.5
{'12JAN03'} 2012.0055 55929 2012 0.00549999999998363 366 2455929.5
[snip]
{'12NOV05'} 2012.846 56236 2012 0.846000000000004 366 2456236.5
{'12NOV06'} 2012.8487 56237 2012 0.848700000000008 366 2456237.5
{'12NOV07'} 2012.8515 56238 2012 0.851499999999987 366 2456238.5
Except there's a huge problem: look at the second entry in the data. 2012.0027 isn't on 2-Jan-2012, it's late on 1-Jan-2012.
>> 366*.0027 * 24
ans =
23.7168
The file does not have enough precision to get this right.
2 Comments
Stephen23
on 2 Mar 2022
Edited: Stephen23
on 2 Mar 2022
"The file does not have enough precision to get this right."
Correct. Which is why I asked for the original data, something we don't yet seem to have:
The start of the 2nd of January 2012 should be:
format long G
D = datetime(2012,1,2,0,0,0)
B = dateshift(D, 'start', 'year'); % midnight at start of the year
E = B + calyears(1); % midnight at the end of the year (do not use DATESHIFT)
Y = year(D);
X = Y + (D-B)./(E-B)
fprintf('%.40f\n',X)
The topic of fractional years has come up before:
Perhaps TMW should implement the conversion to/from fractional years natively as DATETIME methods.
Z = datetime(floor(X),1,1,'Format','yMMdd HHmmss.SSSSSSSSS')
A = Z + mod(X,1).*((Z+calyears(1))-Z)
Peter Perkins
on 3 Mar 2022
My expectation is that in most cases these would not be computed with enough precision to be useful. This is essentially the datenum precision problem:
>> eps(2022)*365.2425*86400
ans =
7.1752e-06
Not to mention even worse round-off: representing even whole days exactly is not possible:
>> 1/365
ans =
0.00273972602739726
I mean, we'll keep an eye on it, but this is a truly terrible time representation.
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!