Decimail Years date to JulianDate
4 Ansichten (letzte 30 Tage)
Ältere Kommentare anzeigen
Ali Guvenaltin
am 25 Feb. 2022
Kommentiert: Peter Perkins
am 3 Mär. 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 Kommentare
Stephen23
am 27 Feb. 2022
Bearbeitet: Stephen23
am 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.
Akzeptierte Antwort
Star Strider
am 27 Feb. 2022
Bearbeitet: Star Strider
am 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 Kommentare
Weitere Antworten (1)
Peter Perkins
am 2 Mär. 2022
Bearbeitet: Peter Perkins
am 2 Mär. 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 Kommentare
Stephen23
am 2 Mär. 2022
Bearbeitet: Stephen23
am 2 Mär. 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
am 3 Mär. 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.
Siehe auch
Kategorien
Mehr zu Dates and Time finden Sie in Help Center und File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!