Calculating lunar/lunisolar holidays in Python

前端 未结 2 464
灰色年华
灰色年华 2021-02-08 22:19

Any calendar nuts here? I\'ve been looking for information on how to calculate the holidays of the current year that occur irregularly in the Gregorian Calendar. Typically thi

相关标签:
2条回答
  • 2021-02-08 22:46

    Even though I do not have code for you I can provide information which may get you some progress.

    First, Julian Date makes sense as the basis for calculating lunar and lunisolar dates because it ticks in SI seconds as measured on the geoid. Formulae for predicting the number of SI seconds between these events can thereby be easily correlated. http://en.wikipedia.org/wiki/Julian_day

    Lunisolar holidays, and planning the Hebrew calendar in general, depend on the correlation of the moon's phase and the solar weekday. In the Hebrew and Islamic calendars, the day begins at sunset. So if the moon reaches 100% phase near sunset, that can affect when the holidays occur and how the calendar is planned into the future. But what time is sunset? That depends not only on the longitude but also on the latitude of observation. Therefore you must plan lunisolar calendars and holidays from a particular location on the geoid. http://en.wikipedia.org/wiki/Jewish_calendar#Principles

    These factors led to the use of simplified ecclesiastical systems, of which there are several in wide use in the world, for the "computus" of the date of Easter, used instead of direct astronomical observation. http://en.wikipedia.org/wiki/Computus

    The requirements of the traditional Islamic calendar, being defined in terms of astronomical observations including sunset, will therefore need to be tied to a particular location on the geoid if you intend to predict holiday dates and time intervals in SI seconds indefinitely into the past or future. This could be the reason for the remarks on "North American sightings" and the errors in future holiday dates that you mentioned; if the observation of moon phase vs solar day is made in North America, rather than say Mecca, the calendar will be planned much differently.

    One inevitable and unpredictable factor in the prediction of any astronomical ephemera, and therefore lunar or lunisolar calendar events, is the change in the Earth's rotation over time. There is a simple formula for estimating this change, but the actual is measured using signals from extremely distant celestial objects. http://en.wikipedia.org/wiki/Leap_second Due to this uncertainty, and to the sensitivity of certain calendars to the correlation between lunar phase and solar ephemeris, there is always a horizon in the (distant?) future for these calendars, past which the sequence of dates is unknowable.

    PyEphem looks like a very cool package and I will check it out myself. If its built-in logic does not meet your needs you are in for quite a time working out how to predict celestial events indefinitely into the future. Here's a taste: http://en.wikipedia.org/wiki/Precession_of_the_equinoxes#Values

    Again, I don't have any specific code for you, but I hope this information is not repeating what you already know and is helpful to you.

    0 讨论(0)
  • 2021-02-08 22:48

    I have coded both of these, using existing libraries.

    Here is the code for Ramadan:

    from convertdate import islamic
    
    def ramadan(year):
        islamic_year = islamic.from_gregorian(year, 1, 1)[0]
        result = islamic.to_gregorian(islamic_year, 9, 1)
        if result[0] < year:
            result = islamic.to_gregorian(islamic_year+1, 9, 1)
        elif result[0] > year:
            result = islamic.to_gregorian(islamic_year-1, 9, 1)
        return date(*result)
    

    Here is the code for Chinese New Year:

    from lunardate import LunarDate
    
    _yot = ('Rat', 'Ox', 'Tiger', 'Rabbit', 'Dragon', 'Snake', 'Horse', 'Goat', 'Monkey', 'Rooster', 'Dog', 'Pig')
    
    def year_of_the(year):
        yr = (year - 2020) % len(_yot)
        return _yot[yr]
    
    def chinese_new_year(year):
        """Returns a tuple of the (date, year_of_the: str)"""
        return (LunarDate(year, 1, 1).toSolarDate(), year_of_the(year))
    

    I opened an enhancement request for convertdate to add them: https://github.com/fitnr/convertdate/issues/24

    0 讨论(0)
提交回复
热议问题