Best way to go from calendar day to Julian day?

I searched around the forum as well as Google and saw a few old email thread on this topic but nothing seems definitive, this is what I have done so far:

TimeScale UTC = TimeScalesFactory.getUTC();
        TimeScale GPS = TimeScalesFactory.getGPS();
        AbsoluteDate ad_jd = new AbsoluteDate(-4712,01,01,12,00,00.000, UTC);

        DateComponents tempDate = new DateComponents(2022, 11, 10);
        TimeComponents tempTime = new TimeComponents(00, 00, 00);


        AbsoluteDate tempDateTime = new AbsoluteDate(tempDate, tempTime, UTC);

        double delta = tempDateTime.durationFrom(ad_jd);

        System.out.println(delta);
        System.out.println(delta/86400);

Is there a more straight forward (or better) ways to do this? Thanks.

Perhaps something like:

 double delta = new DateTimeComponents(2022, 11, 10, 0, 0, 0.0).
                offsetFrom(DateTimeComponents.JULIAN_EPOCH);

Thank you Luc as always, that seems to have worked well and better!

As a follow up question, what is the difference between “DurationFrom” vs “offsetFrom”? In some of my other finding it seems to suggest that using “durationFrom” was better in this case?

@luc

double delta = new DateTimeComponents(2022, 11, 10, 0, 0, 0.0).
                offsetFrom(DateTimeComponents.JULIAN_EPOCH);

Based on your suggestion, the output delta is in seconds I believe. I’m attempting to convert that to ISO8601 date/time but I don’t think my math is correct. Is there a way to use order to convert from Julian day to the iso8601 date and time directly instead of outputing the offsetfrom in seconds.Thanks.

Yes, the offset is in second.

I don’t understand your need. If you already have the calendar elements, building the iso8601 date is done by writing the components with the proper format. I thought you were asking for the way to convert from calendar to non-calendar (i.e. offset), so I’m confused.

@luc

I apologize, I was not thinking clearly when I asked the question. Please allow me to try again.

I want to go from ISO8601 to Julian day (including the fraction day as well). Currently, when using my method or your proposed method, the return is of seconds. I want to take that seconds output to Julian day + fraction day (so something like 2459900.3537). However, if I simply take the output seconds and divide by 86400 I’m not getting the correct answer, and I suspect it is not that simple. So is there a way to go from ISO8601 directly (if there is a method that I’m not seeing) or indirectly to Julian day + fraction day instead of the seconds? Thanks.

Indeed, it is not that simple. The problem is that when using both a reference date very far in the past (the reference date for Julian day was more than 6000 years ago), and time elements in UTC (assuming you are using UTC), there is always the problem of counting or not the leap seconds that occurred in between.

For this reason, I would suggest a two-step approach. The first step would be to count the number of days using for example new DateComponents(year, month, day).getJ2000Day(). The second step would be to count the seconds in the day using for example new TimeComponent(hour, minute, second).getSecondsInUTCDay(). This way, you just ignore the leap seconds and consider the hour, minute, second was already in the time scale you want to work with.

There is another way to do that, using AbsoluteDate.durationFrom(referenceDate, timeScale) but it assumes the reference date was already built taking into account some time scale, so the use of this method is an expert use and needs to understand how time scales work and how irregularities like leap seconds are introduced.

The core problem is that time scales are not regular and that using a continuous real number like a julian day requires some tricks to reconciliate regular and irregular behaviours.

Luc, thanks for the suggestion.

I’m confused about the part that you mentioned the use of new DateComponents(year, month, day).getJ2000Day(). Would this not simply return the number of days since the J2000 epoch? Instead of the Julian day? Maybe I’m missing something. Thanks.

Yes, you are right, I confused two reference dates.
You can try new DateComponents(yers, month;day).getMJD() + 2400000, but beware that julian days start at noon, not midnigth; do you may need to take care of a +1/-1 day offset depending on the hour, and perhaps handle morning and afternoon hours differently due to this day change.

Luc, once again thank you.

I think I should have enough to do the conversion now. Thank you for your help!