Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Maximum Date Supported #7

Open
okeuday opened this issue Apr 19, 2023 · 3 comments
Open

Maximum Date Supported #7

okeuday opened this issue Apr 19, 2023 · 3 comments

Comments

@okeuday
Copy link

okeuday commented Apr 19, 2023

I haven't yet seen the book define the maximum date the lisp routines support. However, based on the function call result in the example below, the maximum Gregorian year should be 2938 or less (at least for the Hindu functions). Once the value is clear, it would be nice if the maximum date (or year) supported was provided by the source code.

>>> import pycalcal as pcc
>>> pcc.hindu_lunar_holiday(9, 1, 2939)
[]

The Gregorian years in ephemeris_correction for the various bounds are much lower than 2938 (i.e., 2019 is the highest Gregorian year, in the first if statement), so the problem above is likely due to the limitations of that function. However, there may be other limitations too.

@okeuday
Copy link
Author

okeuday commented Apr 19, 2023

Ok, the problem above with Gregorian year 2939 is due to lunar month 9 only existing during that Gregorian year with lunar days 20-30 as shown below:

>>> pcc.hindu_lunar_from_fixed(date(2938, 12, 13).toordinal())
[2995, 9, False, 1, False]
>>> pcc.hindu_lunar_from_fixed(date(2940, 1, 1).toordinal())
[2996, 9, False, 1, False]
>>> pcc.hindu_lunar_from_fixed(date(2939, 1, 1).toordinal())
[2995, 9, False, 20, False]
>>> pcc.hindu_lunar_from_fixed(date(2939, 1, 11).toordinal())
[2995, 9, False, 30, False]

I created a general test (provided below) to ensure a conversion to a Hindu lunar date can be reversed with the same source code. So far, it looks like everything works fine up to Gregorian year 3000 at least:

#!/usr/bin/env python3

import pycalcal as pcc
from datetime import date, timedelta

if __name__ == '__main__':
    done = False
    year = 2019
    d = date(year, 1, 1)
    while not done:
        if year != d.year:
            year = d.year
            print(year)
        fixed_solar = d.toordinal()
        lunar = pcc.hindu_lunar_from_fixed(fixed_solar)
        lunar_month = lunar[1]
        lunar_day = lunar[3]
        lunar_leap = lunar[2] or lunar[4]
        fixed_lunar = pcc.hindu_lunar_holiday(lunar_month, lunar_day, d.year)
        valid = fixed_lunar != []
        if valid:
            if (fixed_solar - fixed_lunar[0]) not in frozenset((0, 1)):
                valid = len(fixed_lunar) == 2 and (
                    (fixed_solar - fixed_lunar[1]) in frozenset((0, 1))
                )
                if not valid and lunar_leap:
                    # ignore lunar leap not matching
                    valid = True
        elif lunar_leap:
            # ignore lunar leap not matching
            valid = True
        if valid:
            d += timedelta(days=1)
        else:
            print('failed at', date.fromordinal(fixed_solar),
                  fixed_solar, fixed_lunar, lunar)
            done = True

@okeuday
Copy link
Author

okeuday commented Apr 20, 2023

It looks like CALENDRICA 4.0 changes are required to support the Gregorian year range -1999 to +3000, at least for the ephemeris_correction function results. The additional modifications to the ephemeris_correction function are from the NASA Eclipse website.

So, while nothing breaks when reversing the Hindu lunar date conversion in the script above, the accumulated error from ephemeris_correction (and possibly other functions?) should make the maximum Gregorian year supported by CALENDRICA 3.0 less than 3000. The error should be responsible for the Hindu lunar month 9 (Agrahāyaṇa or Mārgaśīrṣa) shifting into January in the output above (month 9 should be during November/December).

@okeuday
Copy link
Author

okeuday commented May 3, 2023

To avoid the Hindu lunar month 9 shifting into January, it is best to only use Gregorian years less than 2310 (with CALENDRICA 3.0) based on the script:

#!/usr/bin/env python3

import pycalcal as pcc
from datetime import date

if __name__ == '__main__':
    done = False
    year = 1900
    while not done:
        year += 1
        lunar = pcc.hindu_lunar_from_fixed(date(year, 1, 1).toordinal())
        lunar_month = lunar[1]
        lunar_day = lunar[3]
        if lunar_month == 9:
            days = [
                date.fromordinal(fixed)
                for fixed in pcc.hindu_lunar_holiday(lunar_month, lunar_day, year)
            ]
            december = False
            for day in days:
                if day.month == 12:
                    december = True
                    break
            if not december:
                print(year, lunar, days)
                done = True
    print('years valid before', year)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant