How to do math using datetime objects including years

I want to compute the number of days, minutes and seconds since January 1st, 2000 (Julian days) up to a specific date such as June 27, 2022. The "duration" function only allows input formats such as 'dd:hh:mm:ss', but not years. Is there some way to work around this?
date_obs = '22:179:18:42:44.610';
j2000date = '2000:001:12:00:00.000';
formatOut = 'uu:DDD:HH:mm:ss.SSS'; % 22:179:18:42:44.610
j2000format = 'uuuu:DDD:HH:mm:ss.SSS'; % 2000:001:12:00:00.000
Date = duration(date_obs, 'InputFormat', formatOut);
Date2000 = duration(j2000date, 'InputFormat', j2000format);
daysSinceEpoch = Date - Date2000;
Error using duration
Unsupported format 'uu:DDD:HH:mm:ss.SSS'.

 Accepted Answer

date_obs = '22:179:18:42:44.610';
j2000date = '2000:001:12:00:00.000';
formatOut = 'uu:DDD:HH:mm:ss.SSS'; % 22:179:18:42:44.610
j2000format = 'uuuu:DDD:HH:mm:ss.SSS'; % 2000:001:12:00:00.000
Date = datetime(date_obs, 'InputFormat', formatOut)
Date = datetime
28-Jun-0022 18:42:44
Date2000 = datetime(j2000date, 'InputFormat', j2000format)
Date2000 = datetime
01-Jan-2000 12:00:00
daysSinceEpoch = between(Date,Date2000)
daysSinceEpoch = calendarDuration
1977y 6mo 3d 17h 17m 15.39s

2 Comments

How do I convert a calendarDuration to a double? (in this case, 8213.94566)
(also, the "Date" should be 28-Jun-2022, not 0022)
You don't. In order to do that you would need to know how long 1 calendar month is and you can't answer that in isolation. Does that calendar month represent January (31 days) or February (either 28 or 29 days)?

Sign in to comment.

More Answers (2)

date_obs = '22:179:18:42:44.610';
j2000date = '2000:001:12:00:00.000';
These don't look like durations, they look like datetimes. That 12 in your j2000date looks a little suspicious too; did you really mean noon or did you want midnight?
formatOut = 'uu:DDD:HH:mm:ss.SSS'; % 22:179:18:42:44.610
j2000format = 'uuuu:DDD:HH:mm:ss.SSS'; % 2000:001:12:00:00.000
Date = datetime(date_obs, 'InputFormat', formatOut)
Date = datetime
28-Jun-0022 18:42:44
You probably want to add 2000 calendar years here.
Date = Date + calyears(2000)
Date = datetime
28-Jun-2022 18:42:44
Or you could split your string into its components then create the datetime array from the resulting vector.
v = double(split(string(date_obs), ':'));
Date = datetime(v(1)+2000, 1, 0) + days(v(2)) + duration(v(3:5).')
Date = datetime
28-Jun-2022 18:42:44
Date2000 = datetime(j2000date, 'InputFormat', j2000format)
Date2000 = datetime
01-Jan-2000 12:00:00
Now subtract.
timeSinceEpoch = Date - Date2000
timeSinceEpoch = duration
197142:42:44
format longg
daysSinceEpoch = days(timeSinceEpoch)
daysSinceEpoch =
8214.27968298611
Is this result reasonable? Roughly estimating the difference between those two dates is 22 and a half years. What's that in days?
check1 = days(years(22.5)) % or
ans =
8217.95625
check2 = 22.5 * 365 % Units: years * days/year = days
ans =
8212.5
Rather than doing plain subtraction you could use between if you want the difference as a calendarDuration rather than a duration.
d = between(Date2000, Date)
d = calendarDuration
22y 5mo 27d 6h 42m 44.6100000000006s

4 Comments

According to the Python code this was derived from, the interval should be 8213.94566 days. You might have missed a couple of leap days there with your check.
Julian days start at noon. I know, astronomers are just that way. I'm converting right ascension and declination to azimuth and elevation.
After tweaking my code and using "between", I now get: -22y -5mo -26d -22h -42m -44.564s
How do I convert this calendarDuration to a useful number? There's an easy way, and a hard way I'm sure.
(later): I'm working on a method to strip off the alpha characters and leave just the numerics, which I can feed to a date-time to julian date conversion function. This is the "hard way", but apparently the only way.
What should that "useful number" represent? Number of days between those dates, number of seconds, number of years, etc.? I'm guessing either days or seconds, since years have the problem that different years have different lengths.
You probably want the duration answer instead of the calendarDuration answer.
I'm looking for number of days + fraction of a day. For the purposes of this question, I think the "between" function is giving me what I want, although parsing the output string "22y 5mo 27d 6h 42m 44.61s" is a bit of a pain. I think this is a rare instance where the Python datatime object is easier to work with.
There are various algorithms for computing elapsed time including leap years. Here is one of the simplest.
Note: as far as I can tell, there is no "copysign" function in Matlab that will apply the +/- sign of a calculation to the output.
plusOrMinus = 100. * year + month - 190002.5;
if plusOrMinus < 0
plusOrMinus = -1.;
else
plusOrMinus = 1.;
end
result = 367 * year -int32((7 * (year + int32((month + 9) / 12.0))) / 4.0) ...
+ int32((275 * month) / 9.0) + day - 2.5 + (hour + minute / 60. ...
+ second / power(60,2) / 24. - 0.5 * plusOrMinus;

Sign in to comment.

According to the Python code this was derived from, the interval should be 8213.94566 days.
Could you provide the equivalent Python code you used to get 8213.94566? I'd like to make sure I understand the discrepancy.
In your original post you mention the date June 27, 2022, but the timestamp "2022:179:18:42:44.610" is June 28, 2022 at 18:42:44. Is it possible you used a different timestamp in your Python calculation?
Convert the timestamps to datetime
As others have mentioned, these timestamps can be converted to datetime values using the provided formats.
date_obs = "22:179:18:42:44.610";
j2000date = "2000:001:12:00:00.000";
formatOut = "uu:DDD:HH:mm:ss.SSS";
j2000format = "uuuu:DDD:HH:mm:ss.SSS";
Date = datetime(date_obs, InputFormat=formatOut) + calyears(2000)
Date = datetime
28-Jun-2022 18:42:44
Date2000 = datetime(j2000date, InputFormat=j2000format)
Date2000 = datetime
01-Jan-2000 12:00:00
Calculate the number of Julian days between the timestamps
You can simply convert your datetime values to Julian Dates with the convertTo function (or equivalently, the juliandate function) and perform the calculation with these values.
format longG
jd = convertTo(Date, "juliandate")
jd =
2459759.27968299
jd2000 = convertTo(Date2000, "juliandate")
jd2000 =
2451545
jd - jd2000
ans =
8214.27968298597

Categories

Products

Release

R2022b

Asked:

on 2 Dec 2022

Answered:

on 8 Dec 2022

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!