skyfielders / python-skyfield

Elegant astronomy for Python
MIT License
1.41k stars 211 forks source link

Issue with Julian Date conversion #992

Open izzatzubir opened 1 month ago

izzatzubir commented 1 month ago

I was running a calendar conversion for Islamic hijri calendar. I stumbled across an error in interpreting one of the dates, which is between JD = 1976791,1976792. In julian calendar, that date is supposed to be 29 February 700AD. I believe the conversion in skyfield, converted wrongly somehow, to 1st of March 700, and skipped the leap day.

Here's a snippet of the code for the above issue:

    ts = load.timescale()
    ts.julian_calendar_cutoff = GREGORIAN_START
    t = ts.utc(700, 3, 1, 12, 0)
    print(f"jd: {t}")
    print(t.utc_datetime())
    print(t.astimezone(timezone("Asia/Kuala_Lumpur")))

For julian calendar, 29 February 700 exists. but for the above code, it will return:

File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/skyfield/timelib.py", line 544, in utc_datetime_and_leap_second dt = datetime(year, month, day, hour, minute, second, micro, utc) ValueError: day is out of range for month

I did check on the following lines in skyfield/timelib.py, the day was indeed 29 on that Julian date. but I believe since it passed this date to python datetime in dt = datetime(year, month, day, hour, minute, second, micro, utc), it raises that error. Seems that python datetime doesn't support Julian calendar? Is there another way around?

        year, month, day, hour, minute, second = self._utc_tuple(0.5e-6)
        micro = (second * 1e6).astype(int)
        second, micro = divmod(micro, 1000000)
        leap_second = second // 60
        second -= leap_second  # fit within limited bounds of Python datetime
        if self.shape:
            zone = [utc] * self.shape[0]
            argsets = zip(year, month, day, hour, minute, second, micro, zone)
            dt = array([datetime(*args) for args in argsets])
        else:
            dt = datetime(year, month, day, hour, minute, second, micro, utc)
        return dt, leap_second
izzatzubir commented 1 month ago

Just a quick scroll on the current open issue and found this: https://github.com/skyfielders/python-skyfield/issues/957

Should I close this?