Decimail Years date to JulianDate

19 views (last 30 days)
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
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.

Sign in to comment.

Accepted Answer

Star Strider
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')
T1 = 283×3 table
YYMMMDD yyyy.yyyy __MJD ___________ _________ _____ {'12JAN01'} 2012 55927 {'12JAN02'} 2012.0027 55928 {'12JAN03'} 2012.0055 55929 {'12JAN04'} 2012.0082 55930 {'12JAN05'} 2012.011 55931 {'12JAN06'} 2012.0137 55932 {'12JAN07'} 2012.0164 55933 {'12JAN08'} 2012.0192 55934 {'12JAN09'} 2012.0219 55935 {'12JAN10'} 2012.0246 55936 {'12JAN11'} 2012.0274 55937 {'12JAN12'} 2012.0301 55938 {'12JAN13'} 2012.0329 55939 {'12JAN14'} 2012.0356 55940 {'12JAN15'} 2012.0383 55941 {'12JAN16'} 2012.0411 55942
JD = T1.('__MJD') + 2400000.5; % Julian Date
LRP = [T1.('yyyy.yyyy') ones(size(T1,1),1)] \ JD % Linear Regression Parameters
LRP = 2×1
1.0e+00 * 365.250245045822 1721044.00681187
Convert = [T1.('yyyy.yyyy') ones(size(T1,1),1)] * LRP; % Result Is In 'juliandate' Format
Compare = [JD Convert]
Compare = 283×2
1.0e+00 * 2455927.5 2455927.49984406 2455928.5 2455928.48601972 2455929.5 2455929.50872041 2455930.5 2455930.49489607 2455931.5 2455931.51759676 2455932.5 2455932.50377242 2455933.5 2455933.48994808 2455934.5 2455934.51264876 2455935.5 2455935.49882443 2455936.5 2455936.48500009
DT1 = datetime(Convert,'ConvertFrom','juliandate', 'Format','yyMMMdd') % Original Result
DT1 = 283×1 datetime array
11Dec31 12Jan01 12Jan03 12Jan03 12Jan05 12Jan06 12Jan06 12Jan08 12Jan08 12Jan09 12Jan11 12Jan11 12Jan13 12Jan14 12Jan14 12Jan16 12Jan16 12Jan17 12Jan19 12Jan19 12Jan21 12Jan22 12Jan22 12Jan24 12Jan24 12Jan25 12Jan27 12Jan27 12Jan29 12Jan30
DT2 = datetime(round(Convert,1),'ConvertFrom','juliandate', 'Format','yyMMMdd') % Rounded Result
DT2 = 283×1 datetime array
12Jan01 12Jan02 12Jan03 12Jan04 12Jan05 12Jan06 12Jan07 12Jan08 12Jan09 12Jan10 12Jan11 12Jan12 12Jan13 12Jan14 12Jan15 12Jan16 12Jan17 12Jan18 12Jan19 12Jan20 12Jan21 12Jan22 12Jan23 12Jan24 12Jan25 12Jan26 12Jan27 12Jan28 12Jan29 12Jan30
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
Ali Guvenaltin
Ali Guvenaltin on 28 Feb 2022
Thank you so much, my friend...
I just understand the point is finding out a LRP matrix.
I just build a structure that computes LRP coefficients and use them when I need a conversion.
Big thanks again, have a good days!
Star Strider
Star Strider on 28 Feb 2022
As always, my pleasure!
Thank you!

Sign in to comment.

More Answers (1)

Peter Perkins
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
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)
D = datetime
02-Jan-2012
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)
X =
2012.00273224044
fprintf('%.40f\n',X)
2012.0027322404371261654887348413467407226562
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')
Z = datetime
20120101 000000.000000000
A = Z + mod(X,1).*((Z+calyears(1))-Z)
A = datetime
20120101 235959.999998978
Peter Perkins
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.

Sign in to comment.

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!