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

Add Islamic holidays and Chinese New Year to holidays #24

Open
snoopyjc opened this issue Mar 16, 2020 · 5 comments
Open

Add Islamic holidays and Chinese New Year to holidays #24

snoopyjc opened this issue Mar 16, 2020 · 5 comments

Comments

@snoopyjc
Copy link

Enhancement request: Please add Islamic holidays and Chinese New Year to holidays module. Here is a list of them: https://icalendars.net/religion/islamism/

@snoopyjc
Copy link
Author

Here is the code for Ramadan:

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)

@snoopyjc
Copy link
Author

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))

@fitnr
Copy link
Owner

fitnr commented May 16, 2020

Islamic holidays raise an issue because they can occur twice in a Gregorian year. Should the function return a list of date tuples, which isn't in line with the other functions, or return only one of the holidays, which is incomplete behavior?

@snoopyjc
Copy link
Author

snoopyjc commented May 16, 2020 via email

@uy-rrodriguez
Copy link

Hi, have you got anywhere with this request? I think returning both Ramadan dates would be correct.
Based on @snoopyjc 's proposal, something like below.
The second condition was removed, given the Islamic calendar is strictly shorter than Gregorian, I don't think that can ever happen.

def ramadan(year):
    islamic_year = islamic.from_gregorian(year, 1, 1)[0]
    result_1 = islamic.to_gregorian(islamic_year, 9, 1)
    result_2 = islamic.to_gregorian(islamic_year + 1, 9, 1)

    # Ramadan falls towards the end of the Gregorian year
    if result_1[0] < year:
        return ( date(*result_2), )

    # Ramadan falls both at the beginning and end of the Gregorian year
    elif result_1[0] == result_2[0] and result_1 != result_2:
        return ( date(*result_1), date(*result_2) )

    return ( date(*result_1), )

Another option could be to return the "next" date for beginning of Ramadan.

def next_ramadan(year, month, day):
    islamic_date = islamic.from_gregorian(year, month, day)
    # Returns the given date if Islamic date is exactly the beginning of Ramadan
    if islamic_date[1] < 9 or islamic_date[1] == 9 and islamic_date[2] == 1:
        result = islamic.to_gregorian(islamic_date[0], 9, 1)
    else:
        result = islamic.to_gregorian(islamic_date[0] + 1, 9, 1)
    return date(*result)

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

No branches or pull requests

3 participants