Merge pull request #499 from elaav/fix-israel-performance

Fix israel performance
This commit is contained in:
Bruno Bord 2020-05-22 10:26:27 +02:00 committed by GitHub
commit 3c6d7169b8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 124 additions and 117 deletions

View File

@ -2,7 +2,7 @@
## master (unreleased)
Nothing here yet.
- Making the Israel calendar more efficient (#498).
## v9.0.0 (2020-04-24)

View File

@ -1,5 +1,3 @@
from datetime import date, timedelta
from pyluach.dates import GregorianDate, HebrewDate
from ..core import Calendar, FRI, SAT
@ -15,64 +13,52 @@ class Israel(Calendar):
def get_variable_days(self, year):
days = super().get_variable_days(year)
delta = timedelta(days=1)
current_date = date(year, 1, 1)
hebrew_date = GregorianDate(year=year, month=1, day=1).to_heb()
jewish_year = hebrew_date.year
while current_date.year == year:
hebrew_date = GregorianDate(
year=current_date.year,
month=current_date.month,
day=current_date.day,
).to_heb()
jewish_year = hebrew_date.year
month = hebrew_date.month
day = hebrew_date.day
if month == 7:
if day == 1:
days.append((current_date - delta, "Rosh Hashana Eve"))
days.append((current_date, "Rosh Hashana"))
days.append((current_date + delta, "Rosh Hashana"))
elif day == 10:
days.append((current_date - delta, "Yom Kippur Eve"))
days.append((current_date, "Yom Kippur"))
elif day == 15:
days.append((current_date - delta, "Sukkot Eve"))
days.append((current_date, "Sukkot"))
elif day == 22:
days.append((current_date - delta, "Shmini Atzeres Eve"))
days.append((current_date, "Shmini Atzeres"))
elif month == 1:
if day == 15:
days.append((current_date - delta, "Pesach Eve"))
days.append((current_date, "Pesach"))
elif day == 21:
days.append((current_date - delta, "7th of Pesach Eve"))
days.append((current_date, "7th of Pesach"))
elif month == 2:
if day == 5:
independence_date = current_date
if hebrew_date.weekday() == 6:
independence_date = HebrewDate(
jewish_year, month, 4
).to_pydate()
elif hebrew_date.weekday() == 7:
independence_date = HebrewDate(
jewish_year, month, 3
).to_pydate()
elif hebrew_date.weekday() == 2:
independence_date = HebrewDate(
jewish_year, month, 6
).to_pydate()
days.append(
(independence_date - delta, "Independence Day Eve")
)
days.append((independence_date, "Independence Day"))
elif month == 3 and day == 6:
days.append((current_date - delta, "Shavout Eve"))
days.append((current_date, "Shavout"))
current_date += delta
holidays_hebrew_dates = [
(HebrewDate(jewish_year, 6, 29), "Rosh Hashana Eve"),
(HebrewDate(jewish_year + 1, 7, 1), "Rosh Hashana"),
(HebrewDate(jewish_year + 1, 7, 2), "Rosh Hashana"),
(HebrewDate(jewish_year + 1, 7, 9), "Yom Kippur Eve"),
(HebrewDate(jewish_year + 1, 7, 10), "Yom Kippur"),
(HebrewDate(jewish_year + 1, 7, 14), "Sukkot Eve"),
(HebrewDate(jewish_year + 1, 7, 15), "Sukkot"),
(HebrewDate(jewish_year + 1, 7, 21), "Shmini Atzeres Eve"),
(HebrewDate(jewish_year + 1, 7, 22), "Shmini Atzeres"),
(HebrewDate(jewish_year, 1, 14), "Pesach Eve"),
(HebrewDate(jewish_year, 1, 15), "Pesach"),
(HebrewDate(jewish_year, 1, 20), "7th of Pesach Eve"),
(HebrewDate(jewish_year, 1, 21), "7th of Pesach"),
(HebrewDate(jewish_year, 3, 5), "Shavout Eve"),
(HebrewDate(jewish_year, 3, 6), "Shavout"),
]
holidays_hebrew_dates += self.get_hebrew_independence_day(jewish_year)
for holiday_hebrew_date, holiday_name in holidays_hebrew_dates:
days.append((holiday_hebrew_date.to_pydate(), holiday_name))
return days
def get_hebrew_independence_day(self, jewish_year):
"""
Returns the independence day eve and independence day dates
according to the given hebrew year
:param jewish_year: the specific hebrew year for calculating
the independence day dates
:return: independence day dates
in the type of List[Tuple[HebrewDate, str]]
"""
month = 2
day = 5
original_hebrew_independence_date = HebrewDate(jewish_year, month, day)
if original_hebrew_independence_date.weekday() == 6:
day = 4
if original_hebrew_independence_date.weekday() == 7:
day = 3
if original_hebrew_independence_date.weekday() == 2:
day = 6
return [
(HebrewDate(jewish_year, month, day - 1), "Independence Day Eve"),
(HebrewDate(jewish_year, month, day), "Independence Day")
]

View File

@ -1,5 +1,6 @@
from unittest.mock import patch
from datetime import date
import time
from . import GenericCalendarTest
from ..asia import (
@ -552,66 +553,73 @@ class IsraelTest(GenericCalendarTest):
cal_class = Israel
def test_holidays_2017(self):
holidays = self.cal.holidays_set(2017)
self.assertIn(date(2017, 4, 11), holidays) # Passover (Pesach)
self.assertIn(date(2017, 4, 17), holidays) # Passover (Pesach)
self.assertIn(
date(2017, 5, 2), holidays
) # Independence Day (Yom Ha-Atzmaut), was early in 2017
self.assertIn(date(2017, 5, 31), holidays) # Shavuot
self.assertIn(
date(2017, 9, 21), holidays
) # Jewish New Year (Rosh Ha-Shana)
self.assertIn(
date(2017, 9, 22), holidays
) # Jewish New Year (Rosh Ha-Shana)
self.assertIn(
date(2017, 9, 30), holidays
) # Yom Kippur (already a Saturday - Shabbat, weekend day)
self.assertIn(date(2017, 10, 5), holidays) # Sukkot
self.assertIn(date(2017, 10, 12), holidays) # Sukkot
calculated_holidays = self.cal.holidays_set(2017)
known_holidays = {
date(2017, 4, 10), # Passover (Pesach)
date(2017, 4, 11),
date(2017, 4, 16),
date(2017, 4, 17),
date(2017, 5, 1), # Independence Day (Yom Ha-Atzmaut)
date(2017, 5, 2),
date(2017, 9, 20), # Jewish New Year (Rosh Ha-Shana)
date(2017, 9, 21),
date(2017, 9, 22),
date(2017, 9, 29), # Yom Kippur
date(2017, 9, 30),
date(2017, 10, 4), # Sukkot
date(2017, 10, 5),
date(2017, 10, 11),
date(2017, 10, 12),
date(2017, 5, 30), # Shavuot
date(2017, 5, 31),
}
self.assertEqual(calculated_holidays, known_holidays)
def test_holidays_2018(self):
holidays = self.cal.holidays_set(2018)
self.assertIn(date(2018, 3, 31), holidays) # Passover (Pesach)
self.assertIn(date(2018, 4, 6), holidays) # Passover (Pesach)
self.assertIn(
date(2018, 4, 19), holidays
) # Independence Day (Yom Ha-Atzmaut), was delayed in 2018
self.assertIn(date(2018, 5, 20), holidays) # Shavuot
self.assertIn(
date(2018, 9, 10), holidays
) # Jewish New Year (Rosh Ha-Shana)
self.assertIn(
date(2018, 9, 11), holidays
) # Jewish New Year (Rosh Ha-Shana)
self.assertIn(date(2018, 9, 19), holidays) # Yom Kippur
self.assertIn(date(2018, 9, 24), holidays) # Sukkot
self.assertIn(date(2018, 9, 30), holidays) # Sukkot
calculated_holidays = self.cal.holidays_set(2018)
known_holidays = {
date(2018, 3, 30), # Passover (Pesach)
date(2018, 3, 31),
date(2018, 4, 5),
date(2018, 4, 6),
date(2018, 4, 18), # Independence Day (Yom Ha-Atzmaut)
date(2018, 4, 19),
date(2018, 9, 9), # Rosh Hashana
date(2018, 9, 10),
date(2018, 9, 11),
date(2018, 9, 18), # Yom Kippur
date(2018, 9, 19),
date(2018, 9, 23), # Sukkot
date(2018, 9, 24),
date(2018, 9, 30),
date(2018, 10, 1),
date(2018, 5, 19), # Shavuot
date(2018, 5, 20),
}
self.assertEqual(calculated_holidays, known_holidays)
def test_holidays_2019(self):
holidays = self.cal.holidays_set(2019)
self.assertIn(date(2019, 4, 20), holidays) # Passover (Pesach)
self.assertIn(date(2019, 4, 26), holidays) # Passover (Pesach)
self.assertIn(
date(2019, 5, 9), holidays
) # Independence Day (Yom Ha-Atzmaut), was delayed in 2019
self.assertIn(date(2019, 6, 9), holidays) # Shavuot
self.assertIn(
date(2019, 9, 29), holidays
) # Jewish New Year (Rosh Ha-Shana)
self.assertIn(
date(2019, 9, 30), holidays
) # Jewish New Year (Rosh Ha-Shana)
self.assertIn(
date(2019, 10, 1), holidays
) # Jewish New Year (Rosh Ha-Shana)
self.assertIn(date(2019, 10, 9), holidays) # Yom Kippur
self.assertIn(date(2019, 10, 14), holidays) # Sukkot
self.assertIn(date(2019, 10, 20), holidays) # Sukkot
calculated_holidays = self.cal.holidays_set(2019)
known_holidays = {
date(2019, 4, 19), # Passover (Pesach)
date(2019, 4, 20), # Passover (Pesach)
date(2019, 4, 25), # Passover (Pesach)
date(2019, 4, 26), # Passover (Pesach)
date(2019, 5, 8), # Independence Day (Yom Ha-Atzmaut)
date(2019, 5, 9), # Independence Day (Yom Ha-Atzmaut)
date(2019, 6, 8), # Shavuot
date(2019, 6, 9), # Shavuot
date(2019, 9, 29), # Rosh Hashana
date(2019, 9, 30), # Rosh Hashana
date(2019, 10, 1), # Rosh Hashana
date(2019, 10, 8), # Yom Kippur
date(2019, 10, 9), # Yom Kippur
date(2019, 10, 13), # Sukkot
date(2019, 10, 14), # Sukkot
date(2019, 10, 20), # Sukkot
date(2019, 10, 21), # Sukkot
}
self.assertEqual(calculated_holidays, known_holidays)
def test_holidays_2020(self):
calculated_holidays = self.cal.holidays_set(2020)
@ -635,3 +643,16 @@ class IsraelTest(GenericCalendarTest):
date(2020, 5, 29), # Shavuot
}
self.assertEqual(calculated_holidays, known_holidays)
def test_is_holiday_performance(self):
random_date = date(2019, 10, 9)
japan_cal = Japan()
timer = time.time()
for i in range(30):
japan_cal.is_holiday(random_date)
japan_time = time.time() - timer
timer = time.time()
for i in range(30):
self.cal.is_holiday(random_date)
israel_time = time.time() - timer
self.assertGreater(japan_time * 3, israel_time)