Opa_omroep-automatiseren/venv/lib/python3.8/site-packages/convertdate/hebrew.py

175 lines
4.1 KiB
Python
Raw Normal View History

2020-12-27 20:00:11 +00:00
# -*- coding: utf-8 -*-
# This file is part of convertdate.
# http://github.com/fitnr/convertdate
# Licensed under the MIT license:
# http://opensource.org/licenses/MIT
# Copyright (c) 2016, fitnr <fitnr@fakeisthenewreal>
from math import trunc
from . import gregorian
from .utils import jwday, monthcalendarhelper
EPOCH = 347995.5
HEBREW_YEAR_OFFSET = 3760
# Hebrew months
NISAN = 1
IYYAR = 2
SIVAN = 3
TAMMUZ = 4
AV = 5
ELUL = 6
TISHRI = 7
HESHVAN = 8
KISLEV = 9
TEVETH = 10
SHEVAT = 11
ADAR = 12
VEADAR = 13
def leap(year):
# Is a given Hebrew year a leap year ?
return (((year * 7) + 1) % 19) < 7
def year_months(year):
'''How many months are there in a Hebrew year (12 = normal, 13 = leap)'''
if leap(year):
return 13
else:
return 12
def delay_1(year):
'''Test for delay of start of new year and to avoid'''
# Sunday, Wednesday, and Friday as start of the new year.
months = trunc(((235 * year) - 234) / 19)
parts = 12084 + (13753 * months)
day = trunc((months * 29) + parts / 25920)
if ((3 * (day + 1)) % 7) < 3:
day += 1
return day
def delay_2(year):
'''Check for delay in start of new year due to length of adjacent years'''
last = delay_1(year - 1)
present = delay_1(year)
next_ = delay_1(year + 1)
if next_ - present == 356:
return 2
elif present - last == 382:
return 1
else:
return 0
def year_days(year):
'''How many days are in a Hebrew year ?'''
return to_jd(year + 1, 7, 1) - to_jd(year, 7, 1)
def month_days(year, month):
'''How many days are in a given month of a given year'''
if month > 13:
raise ValueError("Incorrect month index")
# First of all, dispose of fixed-length 29 day months
if month in (IYYAR, TAMMUZ, ELUL, TEVETH, VEADAR):
return 29
# If it's not a leap year, Adar has 29 days
if month == ADAR and not leap(year):
return 29
# If it's Heshvan, days depend on length of year
if month == HESHVAN and (year_days(year) % 10) != 5:
return 29
# Similarly, Kislev varies with the length of year
if month == KISLEV and (year_days(year) % 10) == 3:
return 29
# Nope, it's a 30 day month
return 30
def to_jd(year, month, day):
months = year_months(year)
jd = EPOCH + delay_1(year) + delay_2(year) + day + 1
if month < 7:
for mon in range(7, months + 1):
jd += month_days(year, mon)
for mon in range(1, month):
jd += month_days(year, mon)
else:
for mon in range(7, month):
jd += month_days(year, mon)
return int(jd) + 0.5
def from_jd(jd):
jd = trunc(jd) + 0.5
count = trunc(((jd - EPOCH) * 98496.0) / 35975351.0)
year = count - 1
i = count
while jd >= to_jd(i, 7, 1):
i += 1
year += 1
if jd < to_jd(year, 1, 1):
first = 7
else:
first = 1
month = i = first
while jd > to_jd(year, i, month_days(year, i)):
i += 1
month += 1
day = int(jd - to_jd(year, month, 1)) + 1
return (year, month, day)
def to_jd_gregorianyear(gregorianyear, hebrew_month, hebrew_day):
# gregorian year is either 3760 or 3761 years less than hebrew year
# we'll first try 3760 if conversion to gregorian isn't the same
# year that was passed to this method, then it must be 3761.
for y in (gregorianyear + HEBREW_YEAR_OFFSET, gregorianyear + HEBREW_YEAR_OFFSET + 1):
jd = to_jd(y, hebrew_month, hebrew_day)
gd = gregorian.from_jd(jd)
if gd[0] == gregorianyear:
break
else:
gd = None
if not gd: # should never occur, but just incase...
raise ValueError("Could not determine gregorian year")
# tuple: (y, m, d)
return (gd[0], gd[1], gd[2])
def from_gregorian(year, month, day):
return from_jd(gregorian.to_jd(year, month, day))
def to_gregorian(year, month, day):
return gregorian.from_jd(to_jd(year, month, day))
def monthcalendar(year, month):
start_weekday = jwday(to_jd(year, month, 1))
monthlen = month_days(year, month)
return monthcalendarhelper(start_weekday, monthlen)