Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
…nto OsaydAbdu-beta
  • Loading branch information
dr-prodigy committed Feb 10, 2021
2 parents aceb3b8 + 629fda5 commit 83ce9cd
Show file tree
Hide file tree
Showing 4 changed files with 265 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ Portugal PT/PRT None
PortugalExt PTE/PRTE *Portugal plus extended days most people have off*
Romania RO/ROU None
Russia RU/RUS None
SaudiArabia SA/SAU None
Scotland None
Serbia RS/SRB None
Singapore SG/SGP None
Expand Down
1 change: 1 addition & 0 deletions holidays/countries/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
from .portugal import Portugal, PT, PRT, PortugalExt, PTE
from .romania import Romania, RO, ROU
from .russia import Russia, RU, RUS
from .saudi_arabia import SaudiArabia, SA, SAU
from .serbia import Serbia, RS, SRB
from .singapore import Singapore, SG, SGP
from .slovakia import Slovakia, Slovak, SK, SVK
Expand Down
114 changes: 114 additions & 0 deletions holidays/countries/saudi_arabia.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
# -*- coding: utf-8 -*-

# python-holidays
# ---------------
# A fast, efficient Python library for generating country, province and state
# specific sets of holidays on the fly. It aims to make determining whether a
# specific date is a holiday as fast and flexible as possible.
#
# Author: ryanss <ryanssdev@icloud.com> (c) 2014-2017
# dr-prodigy <maurizio.montel@gmail.com> (c) 2017-2021
# Website: https://github.com/dr-prodigy/python-holidays
# License: MIT (see LICENSE file)

from datetime import date

from dateutil.relativedelta import relativedelta as rd
from holidays.constants import FRI, SAT
from holidays.constants import SEP
from holidays.holiday_base import HolidayBase
from holidays.utils import get_gre_date

# Weekend used to be THU, FRI before June 28th, 2013
WEEKEND = (FRI, SAT)


class SaudiArabia(HolidayBase):

"""
There are only 3 official national holidays in Saudi:
https://laboreducation.hrsd.gov.sa/en/gallery/274
The national day holiday is based on the Georgian calendar while the
other two holidays are based on the Islamic Calendar, and they are
estimates as they announced each year and based on moon sightings;
which are:
- Eid al-Fitr*
- Eid al-Adha*
* only if hijri-converter library is installed, otherwise a warning is
raised that this holiday is missing. hijri-converter requires
Python >= 3.6
"""

def __init__(self, **kwargs):
self.country = 'SA'
HolidayBase.__init__(self, **kwargs)

def _populate(self, year):
observed_str = " (observed)"
# Eid al-Fitr Holiday
# The holiday defined from the four days after 29th of
# the 9th month of the Islamic calendar (either from 30/9 to 3/10
# or from 1/10 to 4/10 depending on observed Islamic calendar)

holiday_name = "Eid al-Fitr Holiday"
for hijri_date in get_gre_date(year, 9, 29):
self[hijri_date + rd(days=1)] = holiday_name
self[hijri_date + rd(days=2)] = holiday_name
self[hijri_date + rd(days=3)] = holiday_name
self[hijri_date + rd(days=4)] = holiday_name
if self.observed:
if (hijri_date + rd(days=1)).weekday() in WEEKEND:
self[hijri_date + rd(days=5)] = holiday_name + observed_str
if (hijri_date + rd(days=2)).weekday() in WEEKEND:
self[hijri_date + rd(days=5)] = holiday_name + observed_str
self[hijri_date + rd(days=6)] = holiday_name + observed_str
if (hijri_date + rd(days=3)).weekday() in WEEKEND:
self[hijri_date + rd(days=5)] = holiday_name + observed_str
self[hijri_date + rd(days=6)] = holiday_name + observed_str
if (hijri_date + rd(days=4)).weekday() in WEEKEND:
self[hijri_date + rd(days=6)] = holiday_name + observed_str

# Arafat Day & Eid al-Adha
# date of observance is announced yearly
holiday_name = "Eid al-Adha Holiday"
for hijri_date in get_gre_date(year, 12, 9):
self[hijri_date] = holiday_name
self[hijri_date + rd(days=1)] = holiday_name
self[hijri_date + rd(days=2)] = holiday_name
self[hijri_date + rd(days=3)] = holiday_name

if self.observed:
if hijri_date.weekday() in WEEKEND:
self[hijri_date + rd(days=4)] = holiday_name + observed_str
if (hijri_date + rd(days=1)).weekday() in WEEKEND:
self[hijri_date + rd(days=4)] = holiday_name + observed_str
self[hijri_date + rd(days=5)] = holiday_name + observed_str
if (hijri_date + rd(days=2)).weekday() in WEEKEND:
self[hijri_date + rd(days=4)] = holiday_name + observed_str
self[hijri_date + rd(days=5)] = holiday_name + observed_str
if (hijri_date + rd(days=3)).weekday() in WEEKEND:
self[hijri_date + rd(days=5)] = holiday_name + observed_str

# National Day holiday (started at the year 2005).
# Note: if national day happens within the Eid al-Fitr Holiday or
# within Eid al-Fitr Holiday, then it is not holiday.
holiday_name = "National Day Holiday"
if year >= 2005:
national_day = date(year, SEP, 23)
if national_day not in self:
self[national_day] = holiday_name

if self.observed and national_day.weekday() == FRI:
national_day -= rd(days=1)
self[national_day] = holiday_name + observed_str
elif self.observed and national_day.weekday() == SAT:
national_day += rd(days=1)
self[national_day] = holiday_name + observed_str


class SA(SaudiArabia):
pass


class SAU(SaudiArabia):
pass
149 changes: 149 additions & 0 deletions tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -6049,6 +6049,155 @@ def test_Singapore(self):
self.assertIn(date(2021, 7, 20), self.holidays)


class TestSaudiArabia(unittest.TestCase):

def setUp(self):
self.holidays = holidays.SA(observed=True)

def test_2020(self):
# Eid al-Fitr Holiday
# (skipping 14, and 15 because they are weekends)
self.assertIn(date(2021, 5, 12), self.holidays)
self.assertIn(date(2021, 5, 13), self.holidays)
self.assertIn(date(2021, 5, 16), self.holidays)
self.assertIn(date(2021, 5, 17), self.holidays)
# Eid al-Fitr Holiday
self.assertIn(date(2021, 7, 19), self.holidays)
self.assertIn(date(2021, 7, 20), self.holidays)
self.assertIn(date(2021, 7, 21), self.holidays)
self.assertIn(date(2021, 7, 22), self.holidays)
# National day holiday
self.assertIn(date(2021, 9, 23), self.holidays)

def test_national_day(self):
self.assertIn(date(2020, 9, 23), self.holidays)
# National day started as a holiday at 2005
self.assertNotIn(date(2004, 9, 23), self.holidays)
self.assertIn(date(2005, 9, 23), self.holidays)

def test_national_day_observed(self):
# September 23rd, 2016 was Friday (Weekend)
# so, observed is Thursday
self.assertIn(date(2016, 9, 22), self.holidays)
self.assertIn(date(2016, 9, 23), self.holidays)
self.assertNotIn(date(2016, 9, 24), self.holidays)

# September 23rd, 2017 was Saturday (Weekend)
# so, observed is Sunday
self.assertNotIn(date(2017, 9, 22), self.holidays)
self.assertIn(date(2017, 9, 23), self.holidays)
self.assertIn(date(2017, 9, 24), self.holidays)

def test_national_day_not_observed(self):
self.holidays.observed = False
self.assertNotIn(date(2016, 9, 22), self.holidays)
self.assertNotIn(date(2017, 9, 24), self.holidays)

def test_hijri_based(self):
if sys.version_info >= (3, 6):
import importlib.util
if importlib.util.find_spec("hijri_converter"):
self.holidays = holidays.SA(years=[2020])
# eid alfitr
self.assertIn(date(2020, 5, 23), self.holidays)
self.assertIn(date(2020, 5, 24), self.holidays)
self.assertIn(date(2020, 5, 25), self.holidays)
self.assertIn(date(2020, 5, 26), self.holidays)

# eid aladha
self.assertIn(date(2020, 7, 30), self.holidays)
self.assertIn(date(2020, 7, 31), self.holidays)
self.assertIn(date(2020, 8, 1), self.holidays)
self.assertIn(date(2020, 8, 2), self.holidays)

def test_hijri_based_observed(self):
if sys.version_info >= (3, 6):
import importlib.util
if importlib.util.find_spec("hijri_converter"):
self.holidays = holidays.SA(years=range(2014, 2021))
# observed eid alfitr
self.assertIn(date(2020, 5, 27), self.holidays)

# self.assertIn(date(2016, 7, 10), self.holidays)
# self.assertIn(date(2016, 7, 11), self.holidays)

self.assertIn(date(2018, 6, 18), self.holidays)
self.assertIn(date(2018, 6, 19), self.holidays)

self.assertIn(date(2019, 6, 9), self.holidays)


# osbserved eid aladha
self.assertIn(date(2014, 10, 8), self.holidays)

# self.assertIn(date(2017, 8, 3), self.holidays)
# self.assertIn(date(2017, 8, 4), self.holidays)

# self.assertIn(date(2019, 8, 13), self.holidays)
# self.assertIn(date(2019, 8, 14), self.holidays)


# self.assertIn(date(2017, 8, 6), self.holidays)

def test_hijri_based_not_observed(self):

if sys.version_info >= (3, 6):
import importlib.util
if importlib.util.find_spec("hijri_converter"):
self.holidays = holidays.SA(observed=False, years=range(2014, 2021))
# observed eid alfitr
self.assertNotIn(date(2020, 5, 27), self.holidays)

# self.assertNotIn(date(2016, 7, 10), self.holidays)
# self.assertNotIn(date(2016, 7, 11), self.holidays)

self.assertNotIn(date(2018, 6, 18), self.holidays)
self.assertNotIn(date(2018, 6, 19), self.holidays)

self.assertNotIn(date(2019, 6, 9), self.holidays)


# osbserved eid aladha
self.assertNotIn(date(2014, 10, 8), self.holidays)

# self.assertNotIn(date(2017, 8, 3), self.holidays)
# self.assertNotIn(date(2017, 8, 4), self.holidays)

# self.assertNotIn(date(2019, 8, 13), self.holidays)
# self.assertNotIn(date(2019, 8, 14), self.holidays)

# self.assertNotIn(date(2017, 8, 6), self.holidays)


def test_hijri_based_with_two_holidays_in_one_year(self):
"""
Note: this might required change if weekend changes
took effect in the holiday.SA class (weekend changed
on June 28th, 2013), from (Thursdays and Fridays) to
(Fridays, Saturdays).
Currently, using newest weekend days (Fridays, and Saturdays)
"""
if sys.version_info >= (3, 6):
import importlib.util
if importlib.util.find_spec("hijri_converter"):
self.holidays = holidays.SA(years=[2006])
# eid_alfitr
# 23rd is a weekend day (Saturday), so there
# is a one day shift
self.assertIn(date(2006, 10, 23), self.holidays)
self.assertIn(date(2006, 10, 24), self.holidays)
self.assertIn(date(2006, 10, 25), self.holidays)
self.assertIn(date(2006, 10, 26), self.holidays)
# eid_aladha 1 (hijiry year 1426)
self.assertIn(date(2006, 1, 9), self.holidays)
self.assertIn(date(2006, 1, 10), self.holidays)
self.assertIn(date(2006, 1, 11), self.holidays)
self.assertIn(date(2006, 1, 12), self.holidays)
# eid_aladha 2 (hijiry year 1427)
# The remaining holidays fall in the next year 2007
self.assertIn(date(2006, 12, 31), self.holidays)


class TestSerbia(unittest.TestCase):
def setUp(self):
self.holidays = holidays.Serbia(observed=True)
Expand Down

0 comments on commit 83ce9cd

Please sign in to comment.