公众授权版:normal · 1000 次 · 有效期至 2026-12-31
副本编号 LY-20261007-AC63(水印指纹已嵌入) 含 README、.gitignore;排除 .DS_Store / __pycache__ / .pytest_cache
This commit is contained in:
Vendored
+151
@@ -0,0 +1,151 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import List
|
||||
|
||||
from tyme4py.jd import JulianDay
|
||||
from tyme4py.solar import SolarDay
|
||||
from tyme4py.unit import YearUnit, MonthUnit, DayUnit
|
||||
|
||||
|
||||
class HijriYear(YearUnit):
|
||||
"""回历年"""
|
||||
def __init__(self, year):
|
||||
HijriYear.validate(year)
|
||||
super().__init__(year)
|
||||
|
||||
@staticmethod
|
||||
def validate(year):
|
||||
if year < -640 or year > 9666:
|
||||
raise ValueError(f'illegal hijri year: {year}')
|
||||
|
||||
@classmethod
|
||||
def from_year(cls, year):
|
||||
return cls(year)
|
||||
|
||||
def get_day_count(self):
|
||||
return 355 if self.is_leap() else 354
|
||||
|
||||
def is_leap(self):
|
||||
i = (self._year - 1) % 30
|
||||
return i in (1, 4, 6, 9, 12, 15, 17, 20, 23, 25, 28)
|
||||
|
||||
def get_name(self):
|
||||
return f'{self._year}年'
|
||||
|
||||
def next(self, n):
|
||||
return HijriYear.from_year(self._year + n)
|
||||
|
||||
def get_months(self):
|
||||
months = []
|
||||
for i in range(1, 13):
|
||||
months.append(HijriMonth(self._year, i))
|
||||
return months
|
||||
|
||||
def get_first_month(self):
|
||||
return HijriMonth(self._year, 1)
|
||||
|
||||
|
||||
class HijriMonth(MonthUnit):
|
||||
NAMES: List[str] = ['穆哈兰姆月', '色法尔月', '赖比尔·敖外鲁月', '赖比尔·阿色尼月', '主马达·敖外鲁月', '主马达·阿色尼月', '赖哲卜月', '舍尔邦月', '赖买丹月', '闪瓦鲁月', '都尔喀尔德月', '都尔黑哲月']
|
||||
|
||||
@staticmethod
|
||||
def validate(year, month):
|
||||
if month < 1 or month > 12:
|
||||
raise ValueError(f'illegal hijri month: {month}')
|
||||
HijriYear.validate(year)
|
||||
|
||||
def __init__(self, year, month):
|
||||
HijriMonth.validate(year, month)
|
||||
super().__init__(year, month)
|
||||
|
||||
@classmethod
|
||||
def from_ym(cls, year, month):
|
||||
return cls(year, month)
|
||||
|
||||
def get_hijri_year(self):
|
||||
return HijriYear(self._year)
|
||||
|
||||
def get_day_count(self):
|
||||
d = 29 if self._month % 2 == 0 else 30
|
||||
if self._month == 12 and self.get_hijri_year().is_leap():
|
||||
d += 1
|
||||
return d
|
||||
|
||||
def get_index_in_year(self):
|
||||
return self._month - 1
|
||||
|
||||
def get_name(self):
|
||||
return self.NAMES[self.get_index_in_year()]
|
||||
|
||||
def __str__(self):
|
||||
return f'{self.get_hijri_year()}{self.get_name()}'
|
||||
|
||||
def next(self, n):
|
||||
i: int = self._month - 1 + n
|
||||
return HijriMonth((self._year * 12 + i) // 12, self.index_of(i, 12) + 1)
|
||||
|
||||
def get_days(self):
|
||||
size = self.get_day_count()
|
||||
days = []
|
||||
for i in range(1, size + 1):
|
||||
days.append(HijriDay(self._year, self._month, i))
|
||||
return days
|
||||
|
||||
def get_first_day(self):
|
||||
return HijriDay(self._year, self._month, 1)
|
||||
|
||||
|
||||
class HijriDay(DayUnit):
|
||||
NAMES: List[str] = ['1日', '2日', '3日', '4日', '5日', '6日', '7日', '8日', '9日', '10日', '11日', '12日', '13日', '14日', '15日', '16日', '17日', '18日', '19日', '20日', '21日', '22日', '23日', '24日', '25日', '26日', '27日', '28日', '29日', '30日']
|
||||
|
||||
@staticmethod
|
||||
def validate(year, month, day):
|
||||
if day < 1 or day > HijriMonth.from_ym(year, month).get_day_count():
|
||||
raise ValueError(f'illegal hijri day: {year}-{month}-{day}')
|
||||
|
||||
def __init__(self, year, month, day):
|
||||
HijriDay.validate(year, month, day)
|
||||
super().__init__(year, month, day)
|
||||
|
||||
@classmethod
|
||||
def from_ymd(cls, year, month, day):
|
||||
return cls(year, month, day)
|
||||
|
||||
def get_hijri_month(self):
|
||||
return HijriMonth(self._year, self._month)
|
||||
|
||||
def get_name(self):
|
||||
return self.NAMES[self._day - 1]
|
||||
|
||||
def __str__(self):
|
||||
return f'{self.get_hijri_month()}{self.get_name()}'
|
||||
|
||||
def next(self, n):
|
||||
return self.get_solar_day().next(n).get_hijri_day()
|
||||
|
||||
def is_before(self, target: HijriDay):
|
||||
if self._year != target._year:
|
||||
return self._year < target._year
|
||||
if self._month != target._month:
|
||||
return self._month < target._month
|
||||
return self._day < target._day
|
||||
|
||||
def is_after(self, target: HijriDay):
|
||||
if self._year != target._year:
|
||||
return self._year > target._year
|
||||
if self._month != target._month:
|
||||
return self._month > target._month
|
||||
return self._day > target._day
|
||||
|
||||
def get_index_in_year(self):
|
||||
return self.subtract(HijriDay(self._year, 1, 1))
|
||||
|
||||
def subtract(self, target):
|
||||
return int(self.get_julian_day().subtract(target.get_julian_day()))
|
||||
|
||||
def get_julian_day(self):
|
||||
return JulianDay((11 * self._year + 3) // 30 + 354 * self._year + 30 * self._month - (self._month - 1) // 2 + self._day + 1948055)
|
||||
|
||||
def get_solar_day(self):
|
||||
return SolarDay(622, 7, 16).next(self.subtract(HijriDay(1, 1, 1)))
|
||||
Reference in New Issue
Block a user