公众授权版:normal · 1000 次 · 有效期至 2026-12-31
副本编号 LY-20261007-AC63(水印指纹已嵌入) 含 README、.gitignore;排除 .DS_Store / __pycache__ / .pytest_cache
This commit is contained in:
Vendored
+179
@@ -0,0 +1,179 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
from __future__ import annotations
|
||||
from abc import ABC, abstractmethod
|
||||
from typing import Union, List
|
||||
|
||||
__version__ = '1.5.0'
|
||||
|
||||
|
||||
class Culture(ABC):
|
||||
"""传统文化(民俗)"""
|
||||
|
||||
@abstractmethod
|
||||
def get_name(self) -> str:
|
||||
"""
|
||||
名称
|
||||
:return: 名称
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class Tyme(Culture):
|
||||
@abstractmethod
|
||||
def next(self, n: int) -> Union[Tyme, None]:
|
||||
"""
|
||||
推移
|
||||
:param n: 推移步数
|
||||
:return: 推移后的Tyme或None
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class AbstractCulture(Culture):
|
||||
"""传统文化抽象"""
|
||||
|
||||
@abstractmethod
|
||||
def get_name(self) -> str:
|
||||
pass
|
||||
|
||||
def __str__(self) -> str:
|
||||
return self.get_name()
|
||||
|
||||
def __eq__(self, other: Culture) -> bool:
|
||||
return other and other.__str__() == self.__str__()
|
||||
|
||||
@staticmethod
|
||||
def index_of(index: int, size: int) -> int:
|
||||
"""
|
||||
转换为不超范围的索引
|
||||
:param index: 索引
|
||||
:param size: 长度大小
|
||||
:return: 索引,从0开始
|
||||
"""
|
||||
i: int = index % size
|
||||
return i + size if i < 0 else i
|
||||
|
||||
|
||||
class AbstractTyme(AbstractCulture, Tyme):
|
||||
"""抽象Tyme"""
|
||||
|
||||
@abstractmethod
|
||||
def get_name(self) -> str:
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def next(self, n: int) -> Union[Tyme, None]:
|
||||
pass
|
||||
|
||||
|
||||
class AbstractCultureDay(AbstractCulture):
|
||||
"""带天索引的传统文化抽象"""
|
||||
|
||||
def __init__(self, culture: AbstractCulture, day_index: int):
|
||||
"""
|
||||
初始化
|
||||
:param culture: 传统文化抽象
|
||||
:param day_index: 天索引
|
||||
"""
|
||||
self._culture = culture
|
||||
self._day_index = day_index
|
||||
|
||||
def get_day_index(self) -> int:
|
||||
"""
|
||||
天索引
|
||||
:return: 索引
|
||||
"""
|
||||
return self._day_index
|
||||
|
||||
def get_culture(self) -> AbstractCulture:
|
||||
return self._culture
|
||||
|
||||
def get_name(self) -> str:
|
||||
return self._culture.get_name()
|
||||
|
||||
def __str__(self) -> str:
|
||||
return f'{self.get_name()}第{self.get_day_index() + 1}天'
|
||||
|
||||
|
||||
class LoopTyme(AbstractTyme):
|
||||
"""可轮回的Tyme"""
|
||||
|
||||
def __init__(self, names: List[str], index_or_name: Union[int, str]):
|
||||
"""
|
||||
初始化
|
||||
:param names: 名称列表
|
||||
:param index_or_name: 索引,支持负数,自动轮转; 名称
|
||||
"""
|
||||
self._names = names
|
||||
self._index = self._index_of_by(index_or_name)
|
||||
|
||||
def _index_of_by(self, index_or_name: Union[int, str]) -> int:
|
||||
"""
|
||||
:param index_or_name: 索引或名称
|
||||
:return: 索引
|
||||
"""
|
||||
if isinstance(index_or_name, int):
|
||||
return self.index_of(index_or_name, self.get_size())
|
||||
else:
|
||||
for i in range(0, self.get_size()):
|
||||
if index_or_name == self._names[i]:
|
||||
return i
|
||||
raise ValueError(f"illegal name: {index_or_name}")
|
||||
|
||||
def get_name(self) -> str:
|
||||
return self._names[self._index]
|
||||
|
||||
def get_index(self) -> int:
|
||||
"""
|
||||
索引
|
||||
:return: 索引,从0开始
|
||||
"""
|
||||
return self._index
|
||||
|
||||
def get_size(self) -> int:
|
||||
"""
|
||||
数量
|
||||
:return: 数量
|
||||
"""
|
||||
return self._names.__len__()
|
||||
|
||||
def next_index(self, n: int) -> int:
|
||||
"""
|
||||
推移后的索引
|
||||
:param n: 推移步数
|
||||
:return: 索引,从0开始
|
||||
"""
|
||||
return self._index_of_by(self._index + n)
|
||||
|
||||
def steps_to(self, target_index: int) -> int:
|
||||
"""
|
||||
到目标索引的步数(从左往右顺序)
|
||||
:param target_index: 目标索引
|
||||
:return: 步数(>=0)
|
||||
"""
|
||||
return self.index_of(target_index - self._index, self.get_size())
|
||||
|
||||
def steps_back_to(self, target_index: int) -> int:
|
||||
"""
|
||||
到目标索引的步数(从右往左逆序)
|
||||
:param target_index: 目标索引
|
||||
:return: 步数(<=0)
|
||||
"""
|
||||
n = self.get_size()
|
||||
return -((self._index - target_index + n) % n)
|
||||
|
||||
def steps_close_to(self, target_index: int) -> int:
|
||||
"""
|
||||
到目标索引的最少步数
|
||||
:param target_index: 目标索引
|
||||
:return: 步数(从左往右顺序>=0,从右往左逆序<=0)
|
||||
"""
|
||||
d1 = self.steps_to(target_index)
|
||||
d2 = self.steps_back_to(target_index)
|
||||
if d1 <= abs(d2):
|
||||
return d1
|
||||
return d2
|
||||
|
||||
@abstractmethod
|
||||
def next(self, n: int) -> Union[LoopTyme, None]:
|
||||
pass
|
||||
Vendored
+743
@@ -0,0 +1,743 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
from math import floor
|
||||
from typing import TYPE_CHECKING, List, Union
|
||||
|
||||
from tyme4py import LoopTyme, AbstractCulture, AbstractCultureDay
|
||||
from tyme4py.util import ShouXingUtil
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from tyme4py.culture.star.seven import SevenStar
|
||||
from tyme4py.culture.star.twentyeight import TwentyEightStar
|
||||
from tyme4py.lunar import LunarDay, LunarMonth
|
||||
from tyme4py.sixtycycle import SixtyCycle, EarthBranch
|
||||
from tyme4py.jd import JulianDay
|
||||
from tyme4py.solar import SolarTime, SolarDay
|
||||
|
||||
|
||||
class Animal(LoopTyme):
|
||||
"""动物"""
|
||||
NAMES: List[str] = ['蛟', '龙', '貉', '兔', '狐', '虎', '豹', '獬', '牛', '蝠', '鼠', '燕', '猪', '獝', '狼', '狗', '彘', '鸡', '乌', '猴', '猿', '犴', '羊', '獐', '马', '鹿', '蛇', '蚓']
|
||||
"""名称"""
|
||||
|
||||
def __init__(self, index_or_name: Union[int, str]):
|
||||
super().__init__(self.NAMES, index_or_name)
|
||||
|
||||
@classmethod
|
||||
def from_name(cls, name: str) -> Animal:
|
||||
return cls(name)
|
||||
|
||||
@classmethod
|
||||
def from_index(cls, index: int) -> Animal:
|
||||
return cls(index)
|
||||
|
||||
def next(self, n: int) -> Animal:
|
||||
return Animal(self.next_index(n))
|
||||
|
||||
def get_twenty_eight_star(self) -> TwentyEightStar:
|
||||
"""
|
||||
二十八宿
|
||||
:return: 二十八宿
|
||||
"""
|
||||
from tyme4py.culture.star.twentyeight import TwentyEightStar
|
||||
return TwentyEightStar(self.get_index())
|
||||
|
||||
|
||||
class Beast(LoopTyme):
|
||||
"""神兽"""
|
||||
NAMES: List[str] = ['青龙', '玄武', '白虎', '朱雀']
|
||||
"""名称"""
|
||||
|
||||
def __init__(self, index_or_name: Union[int, str]):
|
||||
super().__init__(self.NAMES, index_or_name)
|
||||
|
||||
@classmethod
|
||||
def from_name(cls, name: str) -> Beast:
|
||||
return cls(name)
|
||||
|
||||
@classmethod
|
||||
def from_index(cls, index: int) -> Beast:
|
||||
return cls(index)
|
||||
|
||||
def next(self, n: int) -> Beast:
|
||||
return Beast(self.next_index(n))
|
||||
|
||||
def get_zone(self) -> Zone:
|
||||
"""
|
||||
:return: 宫
|
||||
"""
|
||||
return Zone(self.get_index())
|
||||
|
||||
|
||||
class Constellation(LoopTyme):
|
||||
"""星座"""
|
||||
NAMES: List[str] = ['白羊', '金牛', '双子', '巨蟹', '狮子', '处女', '天秤', '天蝎', '射手', '摩羯', '水瓶', '双鱼']
|
||||
"""名称"""
|
||||
|
||||
def __init__(self, index_or_name: Union[int, str]):
|
||||
super().__init__(self.NAMES, index_or_name)
|
||||
|
||||
@classmethod
|
||||
def from_name(cls, name: str) -> Constellation:
|
||||
return cls(name)
|
||||
|
||||
@classmethod
|
||||
def from_index(cls, index: int) -> Constellation:
|
||||
return cls(index)
|
||||
|
||||
def next(self, n: int) -> Constellation:
|
||||
return Constellation(self.next_index(n))
|
||||
|
||||
|
||||
class Direction(LoopTyme):
|
||||
"""方位"""
|
||||
NAMES: List[str] = ['北', '西南', '东', '东南', '中', '西北', '西', '东北', '南']
|
||||
"""名称"""
|
||||
|
||||
def __init__(self, index_or_name: Union[int, str]):
|
||||
super().__init__(self.NAMES, index_or_name)
|
||||
|
||||
@classmethod
|
||||
def from_name(cls, name: str) -> Direction:
|
||||
return cls(name)
|
||||
|
||||
@classmethod
|
||||
def from_index(cls, index: int) -> Direction:
|
||||
return cls(index)
|
||||
|
||||
def next(self, n: int) -> Direction:
|
||||
return Direction(self.next_index(n))
|
||||
|
||||
def get_land(self) -> Land:
|
||||
"""
|
||||
:return: 九野
|
||||
"""
|
||||
return Land(self.get_index())
|
||||
|
||||
def get_element(self) -> Element:
|
||||
"""
|
||||
:return: 五行
|
||||
"""
|
||||
return Element([4, 2, 0, 0, 2, 3, 3, 2, 1][self.get_index()])
|
||||
|
||||
|
||||
class Duty(LoopTyme):
|
||||
"""建除十二值神"""
|
||||
NAMES: List[str] = ['建', '除', '满', '平', '定', '执', '破', '危', '成', '收', '开', '闭']
|
||||
"""名称"""
|
||||
|
||||
def __init__(self, index_or_name: Union[int, str]):
|
||||
super().__init__(self.NAMES, index_or_name)
|
||||
|
||||
@classmethod
|
||||
def from_name(cls, name: str) -> Duty:
|
||||
return cls(name)
|
||||
|
||||
@classmethod
|
||||
def from_index(cls, index: int) -> Duty:
|
||||
return cls(index)
|
||||
|
||||
def next(self, n: int) -> Duty:
|
||||
return Duty(self.next_index(n))
|
||||
|
||||
|
||||
class Element(LoopTyme):
|
||||
"""五行"""
|
||||
NAMES: List[str] = ['木', '火', '土', '金', '水']
|
||||
"""名称"""
|
||||
|
||||
def __init__(self, index_or_name: Union[int, str], names: Union[List[str], None] = None):
|
||||
super().__init__(self.NAMES if names is None else names, index_or_name)
|
||||
|
||||
@classmethod
|
||||
def from_name(cls, name: str) -> Element:
|
||||
return cls(name)
|
||||
|
||||
@classmethod
|
||||
def from_index(cls, index: int) -> Element:
|
||||
return cls(index)
|
||||
|
||||
def next(self, n: int) -> Element:
|
||||
return Element(self.next_index(n))
|
||||
|
||||
def get_reinforce(self) -> Element:
|
||||
"""
|
||||
我生者
|
||||
:return: 五行
|
||||
"""
|
||||
return self.next(1)
|
||||
|
||||
def get_restrain(self) -> Element:
|
||||
"""
|
||||
我克者
|
||||
:return: 五行
|
||||
"""
|
||||
return self.next(2)
|
||||
|
||||
def get_reinforced(self) -> Element:
|
||||
"""
|
||||
生我者
|
||||
:return: 五行
|
||||
"""
|
||||
return self.next(-1)
|
||||
|
||||
def get_restrained(self) -> Element:
|
||||
"""
|
||||
克我者(耗)
|
||||
:return: 五行
|
||||
"""
|
||||
return self.next(-2)
|
||||
|
||||
def get_direction(self) -> Direction:
|
||||
"""
|
||||
方位
|
||||
:return: 方位
|
||||
"""
|
||||
return Direction([2, 8, 4, 6, 0][self.get_index()])
|
||||
|
||||
|
||||
class God(LoopTyme):
|
||||
"""神煞"""
|
||||
NAMES: List[str] = ['天恩', '鸣吠', '母仓', '不将', '四相', '鸣吠对', '五合', '三合', '除神', '月德', '月空', '月德合', '月恩', '时阴', '五富', '生气', '金匮', '相日', '阴德', '六合', '益后', '青龙', '续世', '明堂', '王日', '要安', '官日', '吉期', '福德', '六仪', '金堂', '宝光', '民日', '临日', '天马', '敬安', '普护', '驿马', '天后', '阳德', '天喜', '天医', '司命', '圣心', '玉宇', '守日', '时德', '解神', '时阳', '天仓', '天巫', '玉堂', '福生', '天德', '天德合', '天愿', '天赦', '天符', '阴神', '解除', '五虚', '五离', '重日', '复日', '血支', '天贼', '土符', '游祸', '白虎', '小耗', '致死', '河魁', '劫煞', '月煞', '月建', '往亡', '大时', '大败', '咸池', '厌对', '招摇', '九坎', '九焦', '天罡', '死神', '月害', '死气', '月破', '大耗', '天牢', '元武', '月厌', '月虚', '归忌', '小时', '天刑', '朱雀', '九空', '天吏', '地火', '四击', '大煞', '勾陈', '八专', '灾煞', '天火', '血忌', '土府', '月刑', '触水龙', '地囊', '八风', '四废', '四忌', '四穷', '五墓', '阴错', '四耗', '阳错', '孤辰', '小会',
|
||||
'大会', '八龙', '七鸟', '九虎', '六蛇', '天狗', '行狠', '了戾', '岁薄', '逐阵', '三丧', '三阴', '阴道冲阳', '阴位', '阴阳交破', '阴阳俱错', '阴阳击冲', '鬼哭', '单阴', '绝阴', '纯阳', '阳错阴冲', '七符', '成日', '孤阳', '绝阳', '纯阴', '大退', '四离', '阳破阴冲']
|
||||
"""名称"""
|
||||
|
||||
day_gods: List[str] = [
|
||||
';000002300F14156869717A3F;01001617495C40413C425D6A;0209000C041831031906054A5E6B4B5F;033500041A1B032C06054C4D4E60;04002D321C1D1E104F50615152;05111F53546C55433C3E;062E200721220D01566E44;070B2333242F45;08360A2526242F080157583D59;091234080162463C3D5A;0A270728292A5B6364653F79;0B0237130E2B4748727A3E66;0C09020C04300F0314150568696D;0D3504031617495C40413C6F425D6A;0E38183119064A5E6B4B5F;0F001A1B032C064C4D4E60;10002D321C1D1E104F50615152;110B00111F53546C55433C3E;12360A002E200721220D015644;13002333456D;142526242F080157583F3D59;15001234080162463C3D5A;16090004270728292A5B636465;17350204130E032B47483E66;1802300F14156869;19031617495C40413C425D6A;1A1831031906054A5E6B4B5F;1B0B1A1B032C06054C4D4E;1C360A2D321C1D1E104F50615152;1D111F53546C55433C3E;1E2E200721220D01563F44;1F23334573;20090C042526242F080157583D;2135041234080162463C3D5A;22270728292A5B636465;2302130E032B47483E66;2402300F0314150568696E;250B031617495C40413C425D6A;26360A18311906054A5E6B4B5F;271A1B2C06054C4D4E60;282D321C1D1E104F506151523F;29111F53546C55433C3E;2A090C042E200721220D015644;2B350423334567;2C2526242F0857583D59;2D001234080162463C3D5A;2E00270728292A5B63646574;2F0B0002130E032B47483E66;30360A0002300F141505686975;31001617495C40413C425D6A676D;3218311906054A5E6B4B3F675F76;331A1B2C06054C4D4E60;34090C042D321C1D1E104F50615152;353504111F53546C55433C6F3E;362E200721220D5644;3723334567;382526242F08015758703D6759;390B123408016246703C3D5A84;3A360A270728292A5B636465;3B02130E2B47483E66;',
|
||||
';00090002272A536C4C4D4E41717A;0100300F3103233C6151523F66;020004180E032406150543405D;03000C041A1D340617054A5E6B4F50;04002D1B555F;050B112526321C2B3C42654B3E60;060A2E2014100547546246;0712070D161F566A;0822192F0148453D44;092C083301575868695B633C3D;0A0937131E495C6459;0B020721282903727A3F3E5A;0C020427032A05536C4C4D4E416D;0D0C04300F03233C6F61515266;0E38180E24061543405D;0F0B001A1D3406174A5E6B4F5078;100A002D1B555F;1100112526321C2B3C42654B3E60;12002E2014100147546246;130012070D161F566A6D;140922192F080148453D44;152C083301575868695B633C3F3D44;160413031E495C6459;17020C0407212829033E5A;1802272A536C4C4D4E41;190B300F3103233C61515266;1A0A180E032406150543405D;1B1A1D340617014A5E6B4F50;1C2D1B555F;1D112526321C2B3C42654B3E60;1E092E2014100147546246;1F12070D161F56736E6A3F;200422192F080148453D44;210C042C083301575868695B633C3D;22131E495C6459;230B0207212829033E5A;240A0227032A05536C4C4D4E41;25300F31233C61515266;26180E2406150543405D;271A1D340617054A5E6B4F50;28092D1B555F;29112526321C2B3C42654B3F3E60;2A042E2014100147546246;2B0C0412070D161F566A67;2C22192F0848453D44;2D0B002C083301575868695B633C3D85;2E0A0013031E495C6459;2F0002072128293E5A;300002272A05536C4C4D4E4175;3100300F31233C6151526E676D66;3209180E2406150543405D;331A1D340617054A5E6B4F503F76;34042D1B555F;350C04112526321C2B3C6F42654B3E60;362E20141047546246;370B12070D161F566A67;380A22192F08014845703D6744;392C083301575868695B63703C3D74;3A131E495C6459;3B02072128293E5A;',
|
||||
';00000207282931032B717A6E5D59;01000314473C5A;020A000427182526300F1D16062A054F506A;03360B00041A1906055562464066;04002D2C154A5E6B6C733F788B;0512111B0E1E17483C3E;060C2E20321C016869655F;0753544960;08350907210D230810015B63564B3D77;091324081F014C4D4E453C423D;0A2203342F57586461515244;0B02032C4341727A3E;0C0A020407282931032B055D6D59;0D360B040314473C6F5A;0E3827182526300F1D16062A4F506A3F;0F001A19065562464066;10000C2D2C154A5E6B6C86;110012111B0E1E17483C3E;123509002E20321C0168696E655F;13005354495C6D60;1407210D230810015B63564B3D7F;1537130324081F014C4D4E453C423D;160A042203342F57586461515244;17360B0204033343413E;1802072829312B5D3F59;190314473C5A;1A0C27182526300F1D16062A054F506A;1B1A1906055562464066;1C35092D2C154A5E6B6C;1D12111B0E1E17483C3E;1E2E20321C016869655F;1F5354495C60;200A0407210D230810015B63564B3D80;21360B04130324081F014C4D4E453C423D;2222342F5758646151523F44;2302033343413E;24020C072829312B055D59;2514473C5A;26120927182526300F1D16062A054F506A;271A1906055562464066;282D2C154A5E6B6C76;2912111B0E1E17483C3E;2A0A042E20321C016869655F;2B360B045354495C6760;2C07210D2308105B63564B3F3D77;2D00130324081F014C4D4E453C423D;2E000C22342F57586461515244;2F00023343413E;3035090002072829312B05755D59;310014473C676D5A;3227182526300F1D16062A054F506A67;331A1906055562464066;340A042D2C154A5E6B6C;35360B0412111B0E1E17483C6F3E;362E20321C6869653F5F;375354495C6760;380C07210D230810015B6356704B3D677774;391324081F014C4D4E45703C423D;3A350922342F57586461515244;3B023343413E;',
|
||||
';000A00220362463C44;010B00072128291D334F50645D;02360002230605534855423F59;03000212300F24060568695A;0400042E27342A495C403C8C;050C04184A5E6B3E66788D76;06091A1B2B15014C4D4E;07352D321C14175B636151526577;0811130E16080147546C433C6A3D5F;0920070D190801563D60;0A0A032C2F104541;0B0B252631031E1F57584B3E;0C362203056246717B3C3F6D44;0D072128291D334F50645D;0E020423065348554259;0F00020C0412300F240668696E5A;1009002E12342A495C403C;113500184A5E6B3E66;12001A1B2B15014C4D4E;13002D321C14175B63615152656D77;140A11130E0316080147546C433C6F6A3D5F;150B20070D03190801563D60;1636032C2F104541733F;17252631031E1F5758727B4B3E;1804220362463C44;190C04072128291D334F50645D;1A09022306055348554259;1B3502120D0F24060568695A;1C2E27342A495C403C;1D184A5E6B3E66;1E0A381A1B2B15014C4D4E;1F0B2D321C14175B63615152657F;20363711130E0316080147546C433C6A3F3D5F;2120070D03190801563D60;2204032C2F104541;230C042526311E1F57584B3E;2409220562463C44;2535072128291D334F50645D;26022306055348554259;270212300F24060568695A;280A2E27342A495C403C6F;290B184A5E6B3E66;2A361A1B2B15014C4D4E3F81;2B2D321C14175B6361515265678074;2C0411130E03160847546C433C6A3D5F;2D000C0420070D190801566E3D60;2E09002C2F104541;2F35002526311E1F57584B3E;300022056246703C44;3100072128291D334F50645D676D;320A02230605534855426759;330B02120D0F2406056869755A;34362E27342A495C403C3F;35184A5E6B3E6676;36041A1B2B154C4D4E81;370C042D321C14175B6361515265677774;380911130E16080147546C433C6A3D675F;393520070D190801563D60;3A2C2F104541;3B2526311E1F5758704B3E87;',
|
||||
';00001D2F10575868694F503C;0100122B1F495C5564;0209000207222829140605655D44;03000216063305474C4D4E51526A4B3F;04000C042E300F193C6159;0504182C43403E5A;06271A1E2A014A5E6B6C5B6342;070B2D1B1366;080A112526321C0815013C3D;0920032308170153546246413D;0A07210D310324565F;0B0E033448453E60;0C091D2F1005575868694F50717B3C6D;0D122B1F495C553F;0E020C04072228291406655D44;0F000204160633474C4D4E51526A4B;10002E300F193C6159;110B00182C43403E5A;120A00271A1E2A014A5E6B6C5B6342;13002D1B13036D66;14112526321C030815013C6F3D;1520032308170153546246413D;160907210D31032456735F;170E344845727B3F3E60;180C041D2F10575868694F503C;1904122B1F495C5564;1A0207222829140605655D44;1B0B0216063305474C4D4E51526A4B;1C0A2E300F193C6159;1D182C43403E5A;1E38271A1E2A014A5E6B6C5B6342;1F2D1B130366;2009112526321C030815013C3D;21202308170153546246413F3D;220C0407210D3103565F;23040E3448453E60;241D2F1005575868694F503C;250B122B1F495C5564;260A0207222829140605655D44;270216063305474C4D4E51526A4B;282E300F193C6F616E59;29182C43403E5A;2A09271A1E2A014A5E6B6C5B63427988;2B372D1B133F6766;2C0C04112526321C0308153C3D;2D0004202308170153546246413D;2E0007210D3124565F;2F0B000E3448453E60;300A001D2F1005575868694F50703C89;3100122B1F495C5564676D;320207222829140605655D6744;330216063305474C4D4E7551526A4B;34092E300F193C6159;35182C43403F3E5A;360904271A1E2A4A5E6B6C5B634278;37042D1B136766;38112526321C0815013C3D67;390B202308170153546246413D;3A0A07210D3124566E5F;3B0E03344845703E60;',
|
||||
';003509001E2F554C4D4E453C51525D5F;010057586C646160;0200020E06100543;0300020721282923061F0565;0400042E2224533C7344;05360B04182526300F34335B633F3E74;060A1A13016246404B59;070C2D2B4A5E6B5A;0827111B0314082A0148413C3D;0920321C310316080148413C3D;0A35090319154754495C42;0B12070D1D2C174F50563E;0C1E2F05554C4D4E45717B3C51525D6D5F;0D57586C646160;0E02040E061043;0F360B0002040721282923061F653F;100A002E2224533C44;11000C182526300F34335B633E;12001A1303016246404B59;13002D032B4A5E6B6D5A;14350927111B0314082A0148413C6F3D;1520321C310316080168696A3D66;1619154754495C426E;1712070D1D2C174F5056727B3E;18041E2F554C4D4E453C51525D5F;19360B0457586C64613F60;1A0A020E06100543;1B020C0721282923061F0565;1C2E2224533C44;1D182526300F34335B633E;1E3509381A1303016246404B59;1F2D032B4A5E6B5A;2027111B14082A0148413C3D;2120321C3116080168696A3D66;22040319154754495C42;23360B0412070D1D2C174F50563F3E;240A1E2F05554C4D4E453C51525D5F;250C57586C646160;26020E06100543;27020721282923061F0565;2835092E2224533C6F44;29182526300F34335B633E;2A1A13016246404B5982;2B2D2B4A5E6B675A76;2C0427111B0314082A48413C3D;2D360B000420321C3116080168696A3F3D66;2E0A0019154754495C42;2F000C12070D1D2C174F50563E;30001E2F05554C4D4E45703C51525D5F;310057586C6461676D608E;323509020E0610054367;33020721282923061F057565;342E2224533C6E44;35182526300F34335B633E7974;3637041A13036246404B5982;37360B042D2B4A5E6B3F675A76;380A27111B14082A0148413C3D67;390C20321C3116080168696A3D66;3A0319154754495C42;3B12070D1D2C174F5056703E;',
|
||||
';0000302007210D341556;01000217455D;020A0025262B2F060557586C5F;030B001406056246603C8F;0436000207282916105B6364656A;0537130E191F47483E;0622300F2C0168693F44;07021E33495C40413C;08090C04184A5E423D59;093504121A1B0308014C4D4E51524B3D5A;0A02272D321C1D232A4F507E61;0B1124535455433E66;0C0A2E2007210D341505566D;0D0B0217455D;0E3625262B2F0657586C;0F00140662463C4260;10000207282916105B6364656A3F79;1100130E191F47483E;1209350C0422300F032C01686944;1335000204031E33495C40413C6D;1418310308014A5E6B3D59;15121A1B0308014C4D4E51524B3D5A;160A02272D321C1D232A4F507E61;170B1124535455433C6F6E3E66;18362E2007210D341556;190217455D;1A25262B060557586C3F5F;1B14060562463C4260;1C09020C0407282916105B6364656A;1D3504130E03191F47483E;1E22300F032C01686944;1F02031E495C40413C;200A183108014A5E6B3D59;210B121A1B08014C4D4E51524B3D5A;223602272D321C1D232A4F507E61;231124535455433C3E66;242E2007210D34150556717C3F;25021745735D;26090C0425262B2F060557586C5F;27350414060562463C4260;280207282916105B6364656A74;29130E03191F47483E;2A0A22300F2C01686944;2B0B021E33495C40413C6F67;2C36381831034A5E6B3D59;2D00121A1B08014C4D4E51524B3D5A;2E0002272D321C1D232A4F507E613F;2F00112453545543727C3C3E66;3009000C042E2007210D34150556;313500020417455D676D;3225262B2F060557586C70675F;331406056246703C426084;340A0207282916105B6364656A;350B130E191F47486E3E;363622300F032C7544;37021E33495C40413C67;38183108014A5E6B3F3D675976;39121A1B08014C4D4E51524B3D5A;3A09020C04272D321C1D232A4F507E61;3B35041124535455433C3E66;',
|
||||
';000A002E27202C2A475462464B;010B0002070D1E5666;02002F06150548456E5D;0300061705575868695B633C;040002130323495C645F;0507212829249060;0609341001534C4D4E415152;070212300F31031F3C61423F;080418220E032B080143403D44;090C041A1D14080833014A5E6B6C4F503D;0A0A022D1B16556A59;0B0B112526321C193C653E5A;0C2E27202C2A05475462464B6D;0D02070D1E5666;0E2F061548455D;0F000617575868695B633C85;10090002371323495C645F;11000721282903243F3E60;12000403341001534C4D4E415152;1300020C0412300F31031F3C61426D;140A18220E032B080143403D44;150B1A1D140833014A5E6B6C4F503D;16022D1B16556A59;17112526321C193C6F653E5A;182E27202C2A475462464B;1902070D1E5666;1A092F06150548455D;1B061705575868695B633C3F79;1C0204130323495C645F;1D0C040721282903243E60;1E0A03341001534C4D4E415152;1F0B0227300F311F3C6142;2018220E2B080143406E3D44;211A1D140833014A5E6B6C4F503D;22022D1B16556A59;23112526321C193C653E5A;24092E27202C2A0547546246717C4B;2502070D1E56733F66;26042F06150548455D;270C04061705575868695B633C;280A02130323495C645F;290B07212829243E60;2A341001534C4D4E415152;2B0212300F311F3C6F614267;2C3818220E032B0843403D44;2D001A1D140833014A5E6B5B4F503D78;2E0900022D1B16556A59;2F00112526321C19727C3C653F3E5A;3000042E27202C2A05475462464B;3100020C04070D1E56676D66;320A2F0615054845705D67;330B061705575868695B63703C74;34021323495C645F;3507212829243E60;36033410534C4D4E41755152;370212300F311F3C614267;380918220E2B080143403D6744;391A1D140833014A5E6B6C4F503F3D76;3A02042D1B16556A59;3B0C04112526321C193C653E5A;',
|
||||
';00002E20391C246869655D59;010002345354495C5A;023509002707210D062A055B6356515277;0300132B06054C4D4E453C66;04000203142F1557586473614B3F;0512161743416A3E;060C072829310319015F;07360B02032C476C3C6E60;080A04182526300F1D1E0810014F503D;09041A081F01556246403D;0A022D224A5E6B4486;0B111B0E2333483C423E;0C35092E20321C24056869655D6D59;0D02345354495C5A;0E2707210D062A5B635651523F77;0F00132B064C4D4E453C66;1000020C03142F15575864614B;11360B001203161743416A3E;120A0004072829310319015F;13000204032C476C3C6D60;14182526300F1D1E0810014F503D;151A081F01556246403D;163509022D224A5E6B44;17111B0E2333483C6F423E;182E20321C246869655D3F59;1902345354495C5A;1A0C2707210D062A055B635651527F;1B360B3713032B06054C4D4E453C66;1C0A020403142F15575864614B;1D041203161743416A3E;1E0728293119015F;1F022C476C3C60;203509182526300F1D1E08104F503D;211A081F01556246403D;22022D224A5E6B3F447891;23111B0E2333483C423E;240C2E20321C24056869717C655D59;25360B021C5354495C6E5A;260A042707210D062A055B6356515280;270413032B06054C4D4E453C66;2802142F15575864614B;2912161743416A3E;2A35090728293119015F;2B022C476C3C6F6760;2C38182526300F1D1E08104F503F3D;2D001A081F01556246403D;2E0002092D224A5E6B4476;2F360B00111B0E233348727C3C423E;300A00042E20321C24056869655D59;31000204345354495C676D5A;322707210D062A055B6356705152677774;33132B06054C4D4E45703C66;34350902142F15575864614B;3512161743416A3E;36072829310319753F5F;37022C476C3C6760;380C182526300F1D1E0810014F503D67;39360B1A081F01556246403D;3A0A02042D224A5E6B44;3B04111B0E2333483C423E;',
|
||||
';00090038041A221B194C4D4E44;0135000C042D321C2C335B6361655D77;02002E11130E1E06054754433C59;03001220070D0605565A;0400272F2A454142;050B252631032357583E66;06360A0324150162463C;07072128291D34174F50644B;080208015348553F3D5F;0902300F2B080168693D60;0A09041410495C403C6F;0B35090418161F4A5E6B6C5152403E;0C1A221B19054C4D4E6D44;0D2D321C2C335B6361655D77;0E2E11130E1E064754433C6E59;0F0B351220070D0306565A;10360A0027032F2A454142;1100252631032357583E66;12000324150162463C3F;1300072128291D34174F50644B6D;1409020408015348553D5F;1535020C04300F2B080168693D60;161410495C403C;1718161F4A5E6B6C51526A3E;181A221B194C4D4E4481;190B0A2E11130E031E06054754433C59;1A360A2E11130E031E06054754433C59;1B1220070D030605565A;1C27032F2A454173423F;1D252631032357583E66;1E090424150162463C;1F350C04072128291D34174F50644B;200208015348553D5F;2102300F2B080168693D60;221410495C403C92;230B18161F4A5E6B6C51526A3E7893;24360A1A221B19054C4D4E44;252D321C2C335B6361655D7F;26372E11130E031E06054754433C3F59;271220070D030605565A;280904272F2A454142;29350C042526312357583E66;2A2415016246703C;2B072128291D34174F50644B67;2C02085348556E3D5F;2D090002300F2B080168693D60;2E360A001410495C403C;2F0018161F4A5E6B6C51526A3E;30001A221B19054C4D4E717D3F4481;31002D321C2C335B6361655D676D8074;3209042E11130E1E06054754433C6F6759;33350C042720070D0605565A;34272F2A454142;35252631235758703E6687;36241562463C;370B072128291D34174F50644B67;38360A023A015348553D675F;3902300F2B08016869753D60;3A1410495C403C3F;3B18161F4A5E6B6C727D51526A3E76;',
|
||||
';0000380C041A23104A5E6B5B63;010004122D1B13241F838A;020A002E11252622321C3406053C5D44;030B00200306330553544641;040007210D312B5659;050E031448453E5A;060E1D162F2A01575868694F503C6A;0719495C556466;0809020728292C081501515242653D;09021E081701474C4D4E3F3D;0A0C04300F3C6F614B5F;0B041843403E60;0C0A1A2310054A5E6B5B636D;0D0B122D1B1303241F838A94;0E2E11252622321C34063C5D44;0F002003063353546C624641;100007210D31032B5659;11000E031448453E5A;120900271D162F2A01575868694F503C6A;130019495C55643F6D66;14020C040728292C081501515242653D;1502041E081701474C4D4E3D;160A300F3C614B5F;170B1843403E60;181A23104A456B5B6378;19122D1B1303241F9583;1A2E11252622321C033406053C5D44;1B200306330553546C6246416E;1C0907210D31032B567359;1D0E1448453F3E5A;1E0C04271D163B2A01575868694F503C6A;1F0419495C556466;200A020728292C081501515242653D;210B021E081701474C4D4E3D;22300F3C614B5F;231843403E60;241A2310054A5E425B63;25122D1B1303241F;26092E11252622321C033406053C5D44;272006330553546C6246413F;280C0407210D312B5659;29040E1448453E5A;2A0A271D162F2A01575868694F50703C6A89;2B0B19495C55646766;2C020728292C0815515242653D;2D00021E081701474C4D4E3D;2E00300F3C614B5F;2F001843403E60;3009001A2310054A5E6B5B63717D7988;310037122D1B13241F3F676D;320C042E11252622321C3406053C6F5D6744;33042006330553546C624641;340A07210D312B5659;350B0E03144845703E5A;36271D162F2A575868694F503C6A;3719495C55646766;38020728292C081501515242653D67;39021E081701474C4D4E756E3D;3A09300F3C614B5F;3B184340727D3F3E60;',
|
||||
';000A003837041A1316624640425D6A5F;01360B00042D194A5E6B4B60;020009111B032C06100548413C;030020321C310310061F056869;0400224754495C7344;05070D1D334F505651523F3E;063509232F01554C4D4E453C59;070C24575864615A;0802270E34082A01433D;09020721282908016E653D66;0A0A042B15536C3C6F;0B360B0412182526300F14175B633E;0C1A13031605624640425D6A6D5F;0D2D03194A5E6B4B60;0E2E111B33061048413C;0F0020321C31031E061F68693F;1035090022034754495C44;11000C070D1D334F505651523E;1200232F01554C4D4E453C59;130024575864616D5A;140A0204270E0F082A01433D;15360B0204072128290801653D66;162B15536C3C;17121825260D0F14175B633E;181A1316624640425D6A5F82;192D03194A5E6B4B3F60;1A35092E111B032C061048413C;1B0C20321C31031E061F056869;1C224754495C44;1D07121D334F505651523E;1E0A04232F01554C4D4E453C59;1F360B0424575864615A;2002270E34082A01433D;2102072128290801653D66;222B15536C3C;2312182526300F14175B633F3E;2435091A13031605624640425D6A5F;250C2D03194A5E6B4B60;262E111B2C06100548413C;2720321C311E061F056869;280A04224746495C44;29360B04070D1D334F505651523E;2A232F01554C4D4E45703C59;2B2457586461675A96;2C02270E34082A433D;2D0002072128290801653F3D66;2E3509002B15536C3C;2F000C12182526300F14175B633E;30001A1316624640717D425D6A5F82;31002D194A5E6B4B676D6076;320A042E111B2C06100548413C6F67;33360B0420321C311E061F0568696E;3422034754495C44;35070D1D334F50567051523E;36232F554C4D4E453C59;3724575864613F675A;38350902270E34082A01433D67;39020C07212829080175653D66;3A2B15536C3C;3B12182526300F14175B63727D3E7974;'
|
||||
]
|
||||
"""吉神宜趋,凶神宜忌数据(参考 https://www.51wnl-cq.com/ 并进行了部分数据修正)"""
|
||||
|
||||
def __init__(self, index_or_name: Union[int, str]) -> None:
|
||||
super().__init__(self.NAMES, index_or_name)
|
||||
|
||||
@classmethod
|
||||
def from_name(cls, name: str) -> God:
|
||||
return cls(name)
|
||||
|
||||
@classmethod
|
||||
def from_index(cls, index: int) -> God:
|
||||
return cls(index)
|
||||
|
||||
def next(self, n: int) -> God:
|
||||
return God(self.next_index(n))
|
||||
|
||||
def get_luck(self) -> Luck:
|
||||
"""
|
||||
吉凶
|
||||
:return: 吉凶
|
||||
"""
|
||||
return Luck(0 if self.get_index() < 60 else 1)
|
||||
|
||||
@classmethod
|
||||
def get_day_gods(cls, month: SixtyCycle, day: SixtyCycle) -> List[God]:
|
||||
"""
|
||||
日神煞列表(吉神宜趋,凶神宜忌)
|
||||
:return: 神煞列表
|
||||
"""
|
||||
l: List[God] = []
|
||||
index: str = format(day.get_index(), '02X')
|
||||
pattern = re.compile(f';{index}(.[^;]*)')
|
||||
matcher = pattern.search(God.day_gods[month.get_earth_branch().next(-2).get_index()])
|
||||
if matcher:
|
||||
data: str = matcher.group(1)
|
||||
for i in range(0, data.__len__(), 2):
|
||||
l.append(God(int(data[i: i + 2], 16)))
|
||||
return l
|
||||
|
||||
|
||||
class KitchenGodSteed(AbstractCulture):
|
||||
NUMBERS: List[str] = ['一', '二', '三', '四', '五', '六', '七', '八', '九', '十', '十一', '十二']
|
||||
"""数字"""
|
||||
|
||||
def __init__(self, lunar_year):
|
||||
from tyme4py.lunar import LunarDay
|
||||
self._first_day_sixty_cycle = LunarDay.from_ymd(lunar_year, 1, 1).get_sixty_cycle()
|
||||
|
||||
@classmethod
|
||||
def from_lunar_year(cls, lunar_year):
|
||||
return cls(lunar_year)
|
||||
|
||||
def _by_heaven_stem(self, n):
|
||||
return self.NUMBERS[self._first_day_sixty_cycle.get_heaven_stem().steps_to(n)]
|
||||
|
||||
def _by_earth_branch(self, n):
|
||||
return self.NUMBERS[self._first_day_sixty_cycle.get_earth_branch().steps_to(n)]
|
||||
|
||||
def get_mouse(self):
|
||||
return f'{self._by_earth_branch(0)}鼠偷粮'
|
||||
|
||||
def get_grass(self):
|
||||
return f'草子{self._by_earth_branch(0)}分'
|
||||
|
||||
def get_cattle(self):
|
||||
return f'{self._by_earth_branch(1)}牛耕田'
|
||||
|
||||
def get_flower(self):
|
||||
return f'花收{self._by_earth_branch(3)}分'
|
||||
|
||||
def get_dragon(self):
|
||||
return f'{self._by_earth_branch(4)}龙治水'
|
||||
|
||||
def get_horse(self):
|
||||
return f'{self._by_earth_branch(6)}马驮谷'
|
||||
|
||||
def get_chicken(self):
|
||||
return f'{self._by_earth_branch(9)}鸡抢米'
|
||||
|
||||
def get_silkworm(self):
|
||||
return f'{self._by_earth_branch(9)}姑看蚕'
|
||||
|
||||
def get_pig(self):
|
||||
return f'{self._by_earth_branch(11)}屠共猪'
|
||||
|
||||
def get_field(self):
|
||||
return f'甲田{self._by_heaven_stem(0)}分'
|
||||
|
||||
def get_cake(self):
|
||||
return f'{self._by_heaven_stem(2)}人分饼'
|
||||
|
||||
def get_gold(self):
|
||||
return f'{self._by_heaven_stem(7)}日得金'
|
||||
|
||||
def get_people_cakes(self):
|
||||
return f'{self._by_earth_branch(2)}人{self._by_heaven_stem(2)}丙'
|
||||
|
||||
def get_people_hoes(self):
|
||||
return f'{self._by_earth_branch(2)}人{self._by_heaven_stem(3)}锄'
|
||||
|
||||
def get_name(self):
|
||||
return '灶马头'
|
||||
|
||||
|
||||
class Land(LoopTyme):
|
||||
"""九野"""
|
||||
NAMES: List[str] = ['玄天', '朱天', '苍天', '阳天', '钧天', '幽天', '颢天', '变天', '炎天']
|
||||
"""名称"""
|
||||
|
||||
def __init__(self, index_or_name: Union[int, str]):
|
||||
super().__init__(self.NAMES, index_or_name)
|
||||
|
||||
@classmethod
|
||||
def from_name(cls, name: str) -> Land:
|
||||
return cls(name)
|
||||
|
||||
@classmethod
|
||||
def from_index(cls, index: int) -> Land:
|
||||
return cls(index)
|
||||
|
||||
def next(self, n: int) -> Land:
|
||||
return Land(self.next_index(n))
|
||||
|
||||
def get_direction(self) -> Direction:
|
||||
"""
|
||||
:return: 方位
|
||||
"""
|
||||
return Direction(self.get_index())
|
||||
|
||||
|
||||
class Luck(LoopTyme):
|
||||
"""吉凶"""
|
||||
NAMES: List[str] = ['吉', '凶']
|
||||
"""名称"""
|
||||
|
||||
def __init__(self, index_or_name: Union[int, str]):
|
||||
super().__init__(self.NAMES, index_or_name)
|
||||
|
||||
@classmethod
|
||||
def from_name(cls, name: str) -> Luck:
|
||||
return cls(name)
|
||||
|
||||
@classmethod
|
||||
def from_index(cls, index: int) -> Luck:
|
||||
return cls(index)
|
||||
|
||||
def next(self, n: int) -> Luck:
|
||||
return Luck(self.next_index(n))
|
||||
|
||||
|
||||
class Phase(LoopTyme):
|
||||
"""月相"""
|
||||
NAMES: List[str] = ['新月', '蛾眉月', '上弦月', '盈凸月', '满月', '亏凸月', '下弦月', '残月']
|
||||
"""名称"""
|
||||
|
||||
def __init__(self, lunar_year: int, lunar_month: int, index_or_name: Union[int, str]):
|
||||
super().__init__(self.NAMES, index_or_name)
|
||||
from tyme4py.lunar import LunarMonth
|
||||
if isinstance(index_or_name, int):
|
||||
m = LunarMonth.from_ym(lunar_year, lunar_month).next(index_or_name // self.get_size())
|
||||
self._lunar_year = m.get_year()
|
||||
self._lunar_month = m.get_month_with_leap()
|
||||
else:
|
||||
self._lunar_year = lunar_year
|
||||
self._lunar_month = lunar_month
|
||||
|
||||
@classmethod
|
||||
def from_name(cls, lunar_year: int, lunar_month: int, name: str) -> Phase:
|
||||
return cls(lunar_year, lunar_month, name)
|
||||
|
||||
@classmethod
|
||||
def from_index(cls, lunar_year: int, lunar_month: int, index: int) -> Phase:
|
||||
return cls(lunar_year, lunar_month, index)
|
||||
|
||||
def next(self, n: int) -> Phase:
|
||||
from tyme4py.lunar import LunarMonth
|
||||
size = self.get_size()
|
||||
i = self.get_index() + n
|
||||
if i < 0:
|
||||
i -= size
|
||||
i //= size
|
||||
m = LunarMonth.from_ym(self._lunar_year, self._lunar_month)
|
||||
if i != 0:
|
||||
m = m.next(i)
|
||||
return Phase(m.get_year(), m.get_month_with_leap(), self.next_index(n))
|
||||
|
||||
def _get_start_solar_time(self) -> SolarTime:
|
||||
from tyme4py.jd import JulianDay
|
||||
from tyme4py.lunar import LunarDay
|
||||
n = floor((self._lunar_year - 2000) * 365.2422 / 29.53058886)
|
||||
i = 0
|
||||
jd = JulianDay.J2000 + ShouXingUtil.ONE_THIRD
|
||||
d = LunarDay.from_ymd(self._lunar_year, self._lunar_month, 1).get_solar_day()
|
||||
while True:
|
||||
t = ShouXingUtil.msa_lon_t((n + i) * ShouXingUtil.PI_2) * 36525
|
||||
if not JulianDay.from_julian_day(jd + t - ShouXingUtil.dt_t(t)).get_solar_day().is_before(d):
|
||||
break
|
||||
i += 1
|
||||
t = ShouXingUtil.msa_lon_t((n + i + [0, 90, 180, 270][self.get_index() // 2] / 360.0) * ShouXingUtil.PI_2) * 36525
|
||||
return JulianDay.from_julian_day(jd + t - ShouXingUtil.dt_t(t)).get_solar_time()
|
||||
|
||||
def get_solar_time(self) -> SolarTime:
|
||||
t = self._get_start_solar_time()
|
||||
if self.get_index() % 2 == 1:
|
||||
return t.next(1)
|
||||
return t
|
||||
|
||||
def get_solar_day(self) -> SolarDay:
|
||||
d = self._get_start_solar_time().get_solar_day()
|
||||
if self.get_index() % 2 == 1:
|
||||
return d.next(1)
|
||||
return d
|
||||
|
||||
|
||||
class PhaseDay(AbstractCultureDay):
|
||||
"""月相第几天"""
|
||||
|
||||
def __init__(self, phase: Phase, day_index: int):
|
||||
super().__init__(phase, day_index)
|
||||
|
||||
def get_phase(self) -> Phase:
|
||||
"""
|
||||
月相
|
||||
:return: 月相
|
||||
"""
|
||||
return self.get_culture()
|
||||
|
||||
|
||||
class Sixty(LoopTyme):
|
||||
"""元"""
|
||||
NAMES: List[str] = ['上元', '中元', '下元']
|
||||
"""名称"""
|
||||
|
||||
def __init__(self, index_or_name: Union[int, str]):
|
||||
super().__init__(self.NAMES, index_or_name)
|
||||
|
||||
@classmethod
|
||||
def from_name(cls, name: str) -> Sixty:
|
||||
return cls(name)
|
||||
|
||||
@classmethod
|
||||
def from_index(cls, index: int) -> Sixty:
|
||||
return cls(index)
|
||||
|
||||
def next(self, n: int) -> Sixty:
|
||||
return Sixty(self.next_index(n))
|
||||
|
||||
|
||||
class Sound(LoopTyme):
|
||||
"""纳音"""
|
||||
NAMES: List[str] = ['海中金', '炉中火', '大林木', '路旁土', '剑锋金', '山头火', '涧下水', '城头土', '白蜡金', '杨柳木', '泉中水', '屋上土', '霹雳火', '松柏木', '长流水', '沙中金', '山下火', '平地木', '壁上土', '金箔金', '覆灯火', '天河水', '大驿土', '钗钏金', '桑柘木', '大溪水', '沙中土', '天上火', '石榴木', '大海水']
|
||||
"""名称"""
|
||||
|
||||
def __init__(self, index_or_name: Union[int, str]):
|
||||
super().__init__(self.NAMES, index_or_name)
|
||||
|
||||
@classmethod
|
||||
def from_name(cls, name: str) -> Sound:
|
||||
return cls(name)
|
||||
|
||||
@classmethod
|
||||
def from_index(cls, index: int) -> Sound:
|
||||
return cls(index)
|
||||
|
||||
def next(self, n: int) -> Sound:
|
||||
return Sound(self.next_index(n))
|
||||
|
||||
|
||||
class Taboo(LoopTyme):
|
||||
"""宜忌"""
|
||||
NAMES: List[str] = ['祭祀', '祈福', '求嗣', '开光', '塑绘', '齐醮', '斋醮', '沐浴', '酬神', '造庙', '祀灶', '焚香', '谢土', '出火', '雕刻', '嫁娶', '订婚', '纳采', '问名', '纳婿', '归宁', '安床', '合帐', '冠笄', '订盟', '进人口', '裁衣', '挽面', '开容', '修坟', '启钻', '破土', '安葬', '立碑', '成服', '除服', '开生坟', '合寿木', '入殓', '移柩', '普渡', '入宅', '安香', '安门', '修造', '起基', '动土', '上梁', '竖柱', '开井开池', '作陂放水', '拆卸', '破屋', '坏垣', '补垣', '伐木做梁', '作灶', '解除', '开柱眼', '穿屏扇架', '盖屋合脊', '开厕', '造仓', '塞穴', '平治道涂', '造桥', '作厕', '筑堤', '开池', '伐木', '开渠', '掘井', '扫舍', '放水', '造屋', '合脊', '造畜稠', '修门', '定磉', '作梁', '修饰垣墙', '架马', '开市', '挂匾', '纳财', '求财', '开仓', '买车', '置产', '雇佣', '出货财', '安机械', '造车器', '经络', '酝酿', '作染', '鼓铸', '造船', '割蜜', '栽种', '取渔', '结网', '牧养', '安碓磑', '习艺', '入学', '理发', '探病', '见贵', '乘船', '渡水', '针灸', '出行', '移徙', '分居', '剃头', '整手足甲', '纳畜', '捕捉', '畋猎', '教牛马', '会亲友', '赴任', '求医', '治病', '词讼', '起基动土', '破屋坏垣', '盖屋', '造仓库', '交易', '立券', '安机', '会友', '求医疗病', '诸事不宜', '馀事勿取', '行丧', '断蚁', '归岫']
|
||||
"""名称"""
|
||||
|
||||
day_taboo: List[str] = [
|
||||
'8219000776262322200C1E1D,06292C2E1F;0F11185C0001092A0D7014692982837B7C2C2E302F802D2B,06454F2089;111852828370795B302F404533802D152B39201E23221D212726,0F2E1F010D29;004023222088,0F29111847;11180001032A0D70795B2C2E302F802D4E152B33714161201F26,52095847;0F17000102061979454F3A15477677,241F8920;34357C88,7129;1551000403706A454F3A3D771F262322271E1D21,382B415220;0F000102037039297175261F1D21,454F2E156341;00076A54196348767765,792029711552890D382B;11180001020439332C2E302F2B5844477515634C1F2721,0F520D19267A29717020;297170192C2E2D2F2B3E363F4C,0F52156320010347;4C78,297172380D2A2E0F474841;18115C0001702A2C2E2F5282837129795B6375802D154C,1F208924;1811795B032C2E302F802D4163754C27261E1D2120,010D0F29521F;00401D232288,71290F4720;0F170001020E032A70692C2E302F802D2B0D7129474C201F2322,5211183809615D;0F1811000102062A0D2C2D804B2B672E2F7129,70471F8920;0007343588,0F71296B7080;175447440D15828377656A49,2B2E1F892022;11187129705B79000106032A0D397B6F7C802D2C2B61756627261E0C1D21,0F2E154147;0007385476771548,52061F20;0106111839513A2C2E2D2F8B804B4723221F63,71522920;1118000717161A2C2E3371292B56433D6375363F,0F0103472089;161A7888,292E1F0F3861;11180F00012A0D70795D7B7C39332D2C2E4E4863664C,064F478920;5452828379195D00012A0D7B7C2C2E3348156366242526201E,0F7129;00262788,292C2E1F2B2F;040318111A17332C15290D200C7A,47450638;0004031A170F11332C2E302F1571292A657677451949,70201D52;007B343588,87;00010670175B71292A152322271E,03637C2B38;04067033392C7161262322271E1D210C,;000715547776,521F;181100012C2E2F1F,0F38;70076A363F,2920;7888,292E1F;0F707B7C00012F75,5220;528303395B2F1E20,0F01;4088,87;02060418110D332C2E415B637566262322271F20,520F;0F181100012C2E7129,5220;7C343588,87;0001020603691817452C2E2D498244,412B6A096338;393588,87;076A48,45752F29384C0F204F612B;000301394F2E154763751F27,0F707A802629710D1920;4F2C2E2B383F443D433663,0F0147892015;201E27262322,88;0F000102700D335282835329711563,3804897D4520;6A0339332C20528283531563,29713801000F0C47806B;005088,87;291503000D332E53261F2075,0F5238584F45;003988,87;3435000788,87;150001021745512E443D65262322,2B63387C;394888,87;00036A7415384878,45751F20240F522E824F;00010203332C2E2F1558631F,0F1920707A29712646;0717363F1A2C4F3A67433D8A,71290F010347;',
|
||||
'0007010618111A332D302F15262322271E530270164C,560F7129;003988,87;073918111A17332C2E71292322271F1E20481D45548283,38002F70;700F181126151E20001A7919,;5040262788,0F712903;7911192C2E302F00030401060F1571292A75,707C2052;0079701811072C2E01060F33152627200C7A1A302F4576631F2B,80523829;39343588,87;040370181123220F1326271E2021,2915;262322271E202188,1F45;0001060403232226380F767754,56802015;0070071A010618110F5B52836775,632620;00010607155B5C26271E2021165D82,38470F29;3948007888,;528283530339454F0D297115332E2F637520,0F007058;5282835444360F11756415,2C2F29016B472E2B2038;0039504088,;0F0001022E792D3E75663D19,472063703852292B;0F000102032971152C2E19,4720637038522B;343588,87;0F52828303700D332C29712E1F27201E2322,15450175;00261F23221E201D2188,;003988,87;52828354754C2971150301022E,0F63206A0938268941;151A82832627202322,580F7003632E1F297C;00394C786F88,0F2E4420;0704031118528283542D2E4E49201F1E1D2127,292B000C;0F706A151E201D528283544466,47010C2E292F2C38;394088,71294709636F7C44;0F0003450D3329712C2E2F1575,528963705A20587D7C;0F111829711500010370390D332E750C201F,4552822F382B80;0034353988,522E1F;0F1118032A0D545282831A802D2C2E2B71296366774744201F26232221,010900150C;0006261F1E201D212322,0F29381118;0006547677,0F5229151F20;111800010206071979697C67474475664C,0F16298920;000102071282542627201D210C4C78,29580F2E6352031F;00784C793988,0F29702E1F2089;0F03390D332C1929711563261D2E2322,382000521118750C706B;702D155482830F63262720,53292F017D4F38442B2E1F47;4088,030F565A61206B;0F181179005B712980152D4E2A0D533358,52702089;0776776A742623221F200C211D1E,11180F2F5206802B;00343588,060F52;07565A5282835463756677261F20,010F152961;0007363F8A3988,09292C20890F;0F11181200171A7919547638,5215201D;181179000607040D03302F5282834F3A45512B1533664C47,090F702E2089;828354151A4C200C1E23221D212726,030F522E1F;0039787988,1F2E20;111871545282832979397B7C69152B2A0D33485324251F1D1E26,6B00702F800C20;0F18110001027939706954528283685D15565A75201E1D26,29032E;00170F79191A6540,712909387C20;00676588,0F20;0F00071A706A717677492923221E202726,80522E1F;343588,0F5220;111800020D041A796933483E5347446563751F1D212026,010F09150C;262322271E201D21,52450F4F;0038262388,5215;040307177938494C,0F262070;',
|
||||
'0F00030102705282832E544779,2920454F754C38;00010275261E0C2322,6303706F0F292E1F;033945302F828375262720,297071000F2E1F38;000102030F7039453319152E2D2F63751F0C1E20,71290D3847;7917155B0001025D,0F522E3820;38394088,0001202B;0F00175058,5D6B80382E;110F0001702C2E7129201F,5206;0007396A48343588,0F20;111800012A0D2C705271292E201F,15386179;3F656477,0F2B712920;11000170792C2E7129,0F52201F;110F00017052792E1F1E,71290D2B20;0001020626232227201E,0F2E03801F;1179302F832627201E,0071292E1F;0001067052832E71291F20,030F384775;79026A17657603,522E201F;004088,0F014720;010206110F452C2E7129095B5226232227201F0C,58804B036B2B38;69687011180F791966762627201E,0352292E80;00077B7C4834353988,295220;00170F332C2E2D2F802952443F26232227201F,15637C38;006526232227201F,88;0403010218111A17332C2E2D2B15713E6575,4538206429;0007030401021811171A0F2E2322271F1E706749528382,202F2938;000102081A158382262322270C1E,700F292E;1A162623227954,0001710F29;00061A161718110F292A0C26271F21797001022F49,47;1516291211020056,063820;3840,0001202B88;0403080618111A16332E2F152A09537919702C5445490D75072B,80632038;0001081811171A160F1571292A26271E20396476452B0D,632E5238;7B34,87;010206040318110F2E292A27200C70072C302F541F392B49,3815;64262322271F2021,0F2F2938;0002070818111A16175B153E445D5452838265647576,2038454F;000701020618111A1752838254230C7027,26203829;000102261E2027,03476F700F2971382E;15391A302F82835475662627201E,0F702E46290047;0F150370002E0D3979528283532971331F1E20,477D;0F0302791566046F,29710D722A38528283202E45;383940,6370018975202B454F66;3907,87;0F000170390D332E2971152F63751F1E20,52836A38;00397C343548,88;000102030D70332C2E29712F534426201F1E,0F3815;6526232227201F,87;7100030170391959152E2D2F2B,0F201F4F75668938;0F030102392E15634447001F1E,293845200D7075;00161A5D454F153826201E27,7D0D29;1A454F548283,87;0F00010203700D332E2F1929711552828353261F201E2322,;0F171170792F5B1566770001032C2B802D,29387C2071;50400088,87;5C11180001027170520D2983822B15200C,03802E3863;2E260F27201F,523815292F1A;7B7C343588,520F;00060724232227261F2025,520F157929382F;003F651F0C2027232288,0F29;00076A386563,0F7D892066454F52754C;',
|
||||
'00077663,0F29713820;000304080618110F1A2E2D0D3371292A2C302F7566010239454E802B,6320;181117332C2E1526232227201F1E3E,38030F5229;0103040818111A155283262322271E20217A79708230,38472E63;00483F,6338200F;03041A174533302F56795B3E808239528354,700F2920;17262322274050,80387C6B;000F01111A1615292A2627200C2C670279538283543E49,6345;00010618111A16332C2E2F2D27200C07483A450D,15528338;34357B7C,87;002E2F18110F5B3315292A26271F20210C7A70710102393E19,035A;000304111A33152D2E302F71292A5283530770022B,0F634520;1A16170F13152654,3852204F;0018112C2E01040607332D292A09270C2322696870302F47023945,38205280;18111A16175B3315262322271F1E201D215D828354433E363F754551,00030F29;00700F1715262720,472E3863;3F87,2B38200F;030402111A16175B4F3A2B153E0079015D54528382696A51,7006200F;000F1320,63803829;0079181A165B332F2B262322271E2021030469702D4E49712930835D,454F;00030401061A16170F332E71292627200C02696A45514F0D2C2D4E497A,2B;007C343588,87;0F00701783821952712C2E1526271F,03380620;52838253000103297115332E2F19,0F89514F6A66207545;6A170F19,5845754C201F4F3824;0F000301020D297115332E1F0C,16522026;1545332C2E2F83826375662620,0F0003700D71292B;000102060F17705282797823221E2027,2E7129;3F74397677658887,0F384720;5452838203152F802C2D,2E1F20897A700F29710C7D;00010F17505840,565A803852828363;0F00030102700D19297115332C2B535448,2E452089;0F03000102700D29713963451F0C20,528238542F158061;34357B7C88,030F;118283155B20272E1F21,0F0338;0001020607036A5D397C2163664744,0F4E252089;5482836376656419786A,29803020;0F18110001702C2E71291F0D2B152F2127,52821620;1783822C2E5B26201F,0F010D29;00797083821754,0F2E472D4E1F;000739483F66,0F20892B;54528283036F796A153E65,712963;0F17795B54828358,52807C38;0F5C111800015B712952831F20,756A25;01067071292C2E1F20,1103150F52;343588,0F715229;0F170070792C2E261F,0403412322;03027011170D332D2C2E2F716152828354,010F201F;6A170F1963766F,5452201F;030102703945802D2C512B7129092322270C7566,112E5282;1A5D453A332C2E2F4B25262322271F201E1D21,000F7047;007983821A160F1719,632E20471D6B;483F88,87;040318111A16175B795452838215302F6563395D,38702920;000F1323222627,2E38290315;010203040618110F3315292A271D200C6339171A712C2E30491E21,7A;0039262322271E201D210C0748766465776A,150F3829;3435,87;007018111A1617192E15382627201F656477,4F09;00030418111617332E2D2F292A52835407020D302B,090F4520;',
|
||||
'528283530003010215392C20,1112180F29560D2E1F7545;004D64547588,0F29;2A0D11180F52838253037039156358332C2E,38200026;00702C2E164C157126271F1E202425363F,29386A032B;005088,032C2E1F;0F00010206030D7129302F79802D7C2B5C4744,11701D20528338;000403110F527079156523221E2027,0129802E1F6B;00384088,15296763;000102060775261F20,71290F7015;1100010206702D804E2B2620,0F52540D;0007397B7C343588,01065220;0776776564,000F293820;00010206111803302F565A802D4E2B871F261E0C,0D0F52;00763988,0F20;110F70528375660D7129,012E1F2026;0001020617385482,030F47202B6B;0039787088,2E1F89034F206B;0706397B7C794C636A48,520F71294720;02703918110F7919155282756626232227201E,012C2E1F0C;00384088,0F202E157C;5C0001020652825B0E03804B2D4E2B752024210C,292E565A;000103020611187B7C2D4E616439201E0C26,522E4744;000734357B7C3988,0F52822920;87,;0004031811171A5B332C2E155D52,0D292045;0088,090F15;18110F197982832E230C271F1E7A70525463,26202915;00011A1615262322271F1E200C214C,472B0F11;00190F153917701A48,472E1F2003;11037B7C2E2F7129,0F5220;007952151E20,0F2E1F;00384740,0F20;0006522E261F20,0F7129;0F11000170717B,522E1F;007B7C3988,87;076564,0F2920;,87;393588,87;0F03700D33195283825329711563,01260038206B;0F70161715232238828326271F20,7D0352;70504C7888,87;0001030239450D297115332C2E4C,0F54207052833863;110F03706A795215636626271E,0C012F38062C292B;0040395088,87;000103392E54827548,19700F58157A2038;00010203390D3329152C2B751E20,2E1F544753524582;0039343588,87;3F4888,87;000102033911170D3319152E2F0947442627201F,;393488,87;0F0102037039330D5283822971152E1F0C,0026206B;001A1715828344363F261F1E200C2322,0F476B520363;0070784888,0345201F;000102031118396375664819,1D413870208029;0370823F0F6A5215,010D582E1F202C2F29;00387765504088,0F157C;070039201F0C2788,06030F292F;003926271E20747677642322480C06,2E1F;00073934357B7C88,0F52;073F7765644888,0120;',
|
||||
'0F110001702E2F71291F20,06;110001527B7C2E75,0F20;0F11707129,2E1F20;1811002E1F8283,0F20;0F1A0070153871291F20,7A76;3F6588,87;0F1811700001062E2F1F20,7129;18117915384C,5220;07404826271F1E2088,87;0F00010203700D332E2F192971152B52828353631F20,;00037039041A26271F1E202322,0F2F2C335129452E0D3A;0039343588,87;0F0001020370332E2F0D19297115637566302B2C3979,;528283000103451915332C2E631F2720,29716A0D0F70;653988,87;0F00010203528283157033,752971206B452F2B262E;0F000102700D332C2E297115383F631F20,034756;394888,87;528283530370331929272E2B2F631F1D20,0F156B38;1979,3F2F2E45207D;074048261F202322,0F71454F15000180;0F000102030D70332E3919528283532971152B2F201F0C,;0001020339161745514F2C190F1A152E2D2F304979,;3435073988,87;11180F5C000102030D332C2E195329711563261F202322,5283;5282830001032E1570637566302F391F,0F47297120;39701117302F713819297566,004551152C2E201D1F;0001020370528283631575712D2E4E3E581F1E1D,292C2B45262080;0F82833D363F776424,15462F2C52032971;3F8A657788,0F2029702E7D;11180F0001020339700D29716375662E1F2620,38155680;03111A171538193E3F,0F632C2E70454F200C;110F1A6A702C2E1952828353712F6375,4520150001;5282835300010670802D2C2E4E155B201F1E232221,380F71296A;0F1118000102030D70332E2C192971153953631F0C262720,52836125;000739343588,0320;18110F3900010203700D3329711563752E1F0C201D,38525D;000102031811392E2D19528283543E4463751F20,152F1A290F;00657688,6B0F52;0001020311180F702E1F7952828368332D6749443E46630C1E1D21,292B20;0F1700707129385C363F3D1F1E232226,80412B202F;00398A7988,0F20;0F111800017C5C2C2E7129,5270153820;0F1118795B65170002195D,52382E8920;0007711F204840,010F291538;000106025B75712904032D302F382B2A0D801E20,2E1F0F;0F1118060300017B7C792E39767566261F20,71298051;000739343588,8920;074888,06520F38;5282835B79037B7C802D2C2E4E302F2B38493D4463664C1F2021,0F0D7129;63767788,522E0006206B;0F00010206181139702E1F686F6A792D2C304E153375664923221D21,52296B0D80;88,;3F8A6588,1F20;0370110F45510D3371290941614C522623222720,;1966583F6588,87;03700F,79192C2E2D715275262322271F201D21;0F11700001522E71291F20,2B;0F117B7C2C2E71291F20,5203;00343588,87;',
|
||||
'00343588,7129565A;00060403702C2E4C154947443D651F,0D29;528283530339332E152C2F58631F20,380D000F29;006588,29704720;0F1118175C000301027039450D29332C2E2F15631F,895820;0F161A17452F0D33712C2E2B5443633F,150170208903;70786288,06802E1F;0F0001020370390D332C1929712E157563548283534C,202489;5B000102073911522C302F3A678B363F33490D482425200C1E2322,0F15382E1F61;00076A74504088,5229702C7D;0F110001708371292E1F20,0338805156;111817000106702C2E71292A0D33802D302F4E2B44,0F522520;0007343588,290F71;0F5B8270000102060403161A494447,386A418920;11177B7C52832C2E5B1F20,060071292F0F;003888,52201F1D47;000102062A397129797B7C2E1F2425,162F5D2026;0F172C2E387129363F7566512D4E4461,0103475220;008254,06462F2E1F;0F181117795B5C007054292A0D690403332D2C2E66632B3D,89454F38;030270170F45513A2C71295282832A0D532D24252623222720,155A382E1F;00076A0F3874485040,06707C25;5B71297000010611182A0D39792C2E332D4E80151F202621,52454F38;00077665776488,52820F2089;34357B7C7788,0F29;0F705B0004037C5D15653F1F26,522B4738;181179190E332C2E2D52637566262322271F20,;0076645088,87;0F1100017B7C702E7129,522B;1A38712975,0F20;0026271E20,2F2E1F;18117001061579,712920;0F11707B7C5271291E20,2E1F;0F00074850,8920;0F1811705200012E71291F20,38;18117000012C2E7129,5220;87,;0F18110001261F20,0352;037B7C2E2F261F20,0F;006388,87;0F030001027039452971150D332C2F6327,20528283;020F11161A17454F2C2E2D302F2B38434C,20700163;003988,87;0F00010D0302703352828353297115632E,2089454F;03027039450D332C2F2D2971528283636626202322,5815;006A5040077448,702B2C0F2F29;0F00030102700D332E2C192971155382836375261F1E20,;0001020370450D332C2E2D152971,0F528289201D;343588,87;52828354443D65002C2E15495D1F,0F417D712B3863;528283546315332C2E2F26201F2322,0F0D45002971756B;003888,87;393588,87;2C2E2D2B156343364C,0F4729710D708920036A19;00788A88,0671292E;11180F000152548371702C2E2D4E303348492A156144474C63,89201F384506;0F0300017039712952542D2C302F80380D2A363F3349483E616320,1118150C1F2E;0F006A385040740717,1F7063;0F1118000102030D70332C2E192971158283535426201E2322,471F;77766564000788,0F52201E89;',
|
||||
'110001392E1F20,0F7129;00343588,87;0F1152702E2F71291F20,0001;0F1152702E2F71291F20,7A;00385476,521F;0F528300012E7129,0920;363F6526232227201E88,87;0F11700001397129,2E20;0F0001067C1F20,5229;0F705215261E20,012E1F;0F001A651707,565A58202E1F4763;297115030102195282830D332C2E,0F1F5863201D89;0039077426271F1E20,0F29713852822B63;343588,87;0F03706A4F0D332C528283532E29711563,450075;0F0370010239332E2C19528283532971156375262720,;003854637519,205D1D1F52151E21;0001020352666A,0F7020262938172F;00261F2322271E200C88,;007082624C,0F38202E7D4F45471F71;0F000102030D332C2E195282835329716375261E2322,;0F033915666A52261E272048,382E2F6329712C01;003988,87;00010203450D3329152C2E2F5375,0F63896A1D38;39006A26201F,0F520D38580629712B;343588,87;528283542E03700F111869565A7566631F1E2021,297138000C;0F1118000102030D70332C2E195282835329711563261F0C20,47457525;00173882546365756619,466115201F701D475224;0F18000102111A1703154F2C2E382D2F807566,716370891F207D;5D0007363F232227261E21,037C0F471F20;0F00701A17820E544C5C78,7129632E1F382089452F;2C2E5B000739337C38802D44484C2425201F1E272621,52297015;0F11185C0370332D152322528283636626271E,2F292C2E1F000106;000F7765,2E1F7C46;111879690001020370396A2E2D528283543E637566,0F380D582920;00013974150726271F1E200C,0F06520D297170382B45;34353988,0F20;0F528371295B795D2B155333565A446375661F201E272621,00016B0C41;0F181100010603797B7C802D302F2B6743441F202322,2952477D25;11180F71297000010604032A0D793969302F33802D636675,201F52565A1E;11180F000704030D7C684580302F153867534775,702041;00262322271F1E203F8A65,52290F0380;002C7080305C784C62,2E1F4720;000704036939487C4466,0F70112938;54528283700001020339482D301571565A363F637566,06292B201F89;005040,522E1F0F2C20;18110001032A0D835B7129302F791533536678,0F20891F1D;076A7626271F1E20,0D0F29382F2E;7B7C343588,0F70;11180F71297052828354792A0D33802D153853201F1E212627,012F564766;0001067011185B0D332C2E2D712909262322271F200C,0F526325;00195475667688,5229152E20;0004037B7C0F79494766754667,802938692089;003F657788,7152290F032B;525400045B17791A565D754C7866,2E1F207C;71297C790001062A0F802D,5215705D;0470170F191A134C8283662426232227201E,;00170F7665776488,;074888,87;',
|
||||
'0F0001020D700339332C192A82832971152E1F0C20262322,0652563861;1F2027260076232288,0F295282;34357C88,0111180F2920;0F030001022A0D3945297115528283637020,476A382E1F44;5B11180001020328700D332C2E195282837115632F751F2720,290F4766;0F0001021A175D2C19152E302F7182836379,8920704F754541;0F11180300706A2E1549466319,292F26806B382B207545;00704F0D332C2E2D15363F261F20274C,0F2906036F47;0F11180001027039302971542F7526201E,63472E151F58;390001022C2E302F1575804B2D261F20,0D0F0319707D5229717A;076A79040363660F5D363F,52292E1F20382F155601;006A38075040,0F630141202B454F;0F1118000106287129705B032C2E302F802D4E2B201F,5283583841;002876396577261F20,5282290F;07343588,0652;181100012A0D52832953411E20,2E1F0F4715;0F0001062871292E7C528283032C5C2A15767765,11185D89206B;0F181138171A7975665B52835415,47701F8920;0F181100062839707952542C2E302F03565A7566441F1E,0D29802B20;0F280001363F8A4326232220,2E1F47032F7D;0F17000728705448757A,522E1F15562F;00076A74173926271F1E20,0F7029522B;04170F79195D1A637566363F76,01522E8920;700718111A302F717566,0F2B2E20;11180F000128032A0D7129302C2E2F2D802B09411F1E20,52835438;0076777566262322271F201E,0F11185229;34357C88,8920;010670170F0E3A294152828354262322271F201E,2E181544;01023918112E2D493E52756624262322271F20,;04033918110F0D2C2E7129332D2B72528283547566,;017018110F1A2E15495247828363462322271F,;0F000106387129,2E1F;0F707500261E20,382E1F;181100012C2E2F1F20,0F52;181170792C2F7129,5220;07504088,0F01;0F0001062E7129,5220;7665261F20,0F29;077C343588,87;0F18117052000171291E20,2E1F;0F181100017B7C2E71291F20,036F;181100015B3875,2E20;0F000102702E15471F1E,294F2B452C2F2680;0F000102700D332C712E15261F201E,80036A614738;0001020370392F80712B546675201E26,1F58472E15;0039076A7426271F2048,0F79197029717A38;04031975363F6366,0F5401202C5282832E2F;3807504088,87;00020370454F0D3933192C2E2D156375261F202322,0F71;003F261F202788,87;343588,87;002627651E20232288,87;0F0D33000103452E528283297115752620,63386F70;0003391982835475,2E1F0F6A702971722A0D;0F00010203703915632719792322,8026204529715875;002E4344793F26271F20,03702C2F292B381A;001A2B5448701938754C,152E202425;0039332C2E2D2F152B4644261F1E,0F7019382971637A;11180370392A0D3329712C2F156375795B5D,450C8900382E1F2001;5040000738,0F7D7C584F012063452B;',
|
||||
'000150402627,0F292F2B;0079110F0304062A528323222627207A19701A2C2E2F5D82,2945;001779332D2322271E2007760304,38290F;0007343588,71297063;0004037039180F332D152952262322271F0C533A82,41178047;0079192E2F030417332D1552837A5D,4E20;001A170F1379232227761926,712938;87,26205282;001A170F5B332E2D7129261E203E5D,15035282;007022230726,2E17712952302F;00077A7088,87;87,;07262723221F40,0F712952;0F000102070D70332C2E19528283297115637526201E2322,;03392D2E332F211D201F1E27,0F7015380029710D1958;343588,87;0F0102700D332C2E2F0319528283531529716345261F2322,;5282835300031929150D332C2E63,0F21704520897175;006A79190F6F2627,6B4620453829;00211D1E232288,;0F7045332C2E71201F1D21,47011552295303;00704888,87;0F00040370396A742E15444948,4589384F20;5282835303702971150D2F,38896A6D0F20;0007504088,87;0F00010203700D332C2E1929711552828353637526202322,;393588,87;007C343588,87;0F11180003706A4F0D332C2E192971155363751F20262322,5247464161;528283545363000103332E15,0F1F197029710D757D20;0F006A1938271779,565A4575522F801F1E63;001D23221E2788,52290F2E1F20;0F175B3975660745514F2B4825201E211D,010352292E;007007482088,2E1F5847;0F110039702C2E522F1574487B7C2D4E804B,098920453861;111852828353546319297115030D332B2C,060F892E38201F;0007504088,0F291570;030102062C2E543E3D636679,380D1946297100;0339332C2E302B66201D1F27,0D2971010015520F6B;34357B7C88,7129;0F111800010203700D332C2E192971152F4B49471F270C2322,52562B20;0F111800010203391929710D1552828353,2075708945630941;00177688,0F52804F25;00396577647969271E2322,52012E1F262061;1707702C2E71291F20,0F52000106111D;0070,0F292C2E791F;0F18110001702C2E7129,6F454F098920;705282835B0D2F71,0F202E41;0007504088,060F71702F29;0F5C5B0001032A0D7052832C2E71291F20,1118517D46;07762623221F1E20,000F1552296B2F;88,6B;181100012A0D2C2E2F2B2D304E447129831F,0F0941613820;03020E0F18110D332C2E2D2F4971293E615244756653,892025;000F76,032E1F522C292B;0028397976771E232227,0F522E474420;7039170F45513A2C2E7129242526271F201D,0001035215;0001027007824878,2E3889201D;703911170E2C2E2D2F4B15712952633D,092B8920;03047039171A533852443D363F,;',
|
||||
'111879076A1A171523221E272024,5229700F1D012E2B0C2F;390050404C88,0F5282296920;261F1E20232288,52290058363F;0F0001020370332C2E2F1575261F,2971476A45825238;0007343588,0F292F7020;00021719792B155D5466774962,010611180F2920;0F1118528283530001035C702971152B332C2E63201F1E23222621,6B75452D4F80;00177179546A76,0F52443D1F;0001020603700F7B7C2E1F692D48302F565A586366240C21,2B151A2920;0F1A1716007015713F261F2720,5263587D2B4703;005C702C2F802B154C78,5A562E1F2089454663;00037039454F0D332971152C4C48,090F476341382E;11185282837975661271393D692D15565A201E262322,292F060D0C;004088,0F52;767788,5282002920;0F111800010206032A0D097170292D302F1575761320,521F4725;000739343588,520F;181179828354637566,0F52290120;5C0F1811790070528371291F20,2F03805125;003854767788,2E1F5220;0F18110001707B7C0D7129,52565A152B20;170007386A7448363F261F1E,030F79636F20;11180F000102587B7C5282837971302F804B2B497675,09612E1F20;705C4C39171A4F0E7971295B5248,0F2E1F1D;076A171552837982546578,712970010F;004C504088,0F521547;7665262322271F201E21,0F00298071;00010206090D5B7952828354685D7B7C443D77656366201F1E,030F47454F;343588,87;790F181113332C2E2D302F1554,70012038;00040301067018111A0F332C15292A261E200C7A7919712F5D52828354,5617454F;003826232277,632E2052;000106073018110F3329271E0C7A0D75,38262015;0F005B261F20,2E2F;384C,8920;076A696819,0F29;036F791E20,522E1F;00654C88,;262322271F1E20,7129;0F18117000012E71291F20,527A;0039343588,;1811795B5466,0120;0F1811705200012E71291F20,062B;003F88,87;000102035270392E2D5863,0F381D2B29212015;00391A6A15384C4943363F7448,0F0379472B63;00701A17794C0F302F715475,2E454F892024;000102037039714515750D33,201D381F092E0F11;5282835479036A2627201E,0F380D70297115012F;4C4088,87;261F201E232288,;002627241F1E20232288,;0039343588,87;0F0211195465756679,2F384570202B6A;0F0052037029710D332C15,7545584F89201D21;0F003854,20521D21;0F0001020370390D1952828353542971631F0C,1520;0F0001022E154826271F1E203874362322,0363;0001020370392F2971152B54754C,45891F0F2046;000370396A450D332F4B154C,0F20897D41381F2E;',
|
||||
'00790F072C2E0103047018111A262322271E7A302F5448637545,29381556;6A79363F65,0F292B71;000118111A332C2E2D1571292A23222627200C7A791970302F5D5282835456,387C454F;000118111A332C2E2D1571292A2627200C7A1979,387C;00040318110F1519262322271E2021,52821F38;0039343588,87;00390103040618111A17332C2E262322271E157A7071302F45631F2075,807C;000118111A16175B154C26271E200C232279302F5D528283547543,0F297C7A;074888,87;87,;010670181126271F202165,2938;000770171988,0F2E2038;000106040318111A170F33292A26276A201D0C7A71077C1F1E74694F,52;87,;5282835354037029711575262720,631F58000F2E3801;0F0001020370390D3319297115632E2C752620212322,;0339332C2E1575201E26,0F520D631F29712A724738;343588,87;0F00030D70332C2E3952828353542971156375,6B20;00010203396A79637566201D211E,29387D71707A;00076527262322,1552825A201D0F38;3988,;1500443626271F1E,29710F47380D195203;000788,;0F0370390D332C192E2971637547202322,5815;031A2B7915656A,0F177001204529710D632E2F;0F03700D332C2E2971152F52828363,01004547380C;0F000102030D7033528283534529711520,634758;006A6F391974,0F2E614447702C292F71201F3852;34357B7C88,0F20;11180F00010E715229702E79692C2D2B15093954444C66,2F565A8061;000102033945332C6375201D21,0F1929710D70;07487677393F88,0F2952151F1D;0F17000102060370392E52828353331F,452F2C266A79292B2038;161A0F1526271F4C,5861034738;3950177088,522E1F0F20;11180F0001020370391952835329712B632E7B7C792D2C8020,385D15;00046A7966444C7765,010C202F38520F70292E;70545282832E71291A7933192A5D5A5040,090C384F4520891D6B;0F11180006032A0D70332E011954828371152C202322,58477D63;0F111800037039450D2971332C632026,1F2E2B385282;003934357B7C88,0F20;00481F2023221E27262188,0F292C2E;18117900012C2E5B1F20,0F710D5229;000776776548,0F1118152E1F20;5254700001020612692D4E584647336375662E1F1E,71290D2620;006A583F232227261F20,0F29154703;00077088,522E1F8920;0F5C707971292C2E0E032A0D6A804B2D8B2B3348634C,521109154620;04795B3F651A5D,0F52010620;117154528283292C2E302D4E092A0D50407970443D,56804100;18115452830001712970802D2C2E302F2B2A0D78791F,0F20475861;0F1811000104037115454F7677657B7C392023222726210C,52092E1F;34350088,0F20;0F111800171A454F514E3A3871157765443D23221E262720,80612E1F;111800010206037939695482835D2D2E4E446375661F262120,0F52290D71;767779392623222788,152B1F1D20;000102060717706A33392D2E4E674447482322271E210C,71292B4F20;0F171511793F76584C,0347200C1D;000788,87;'
|
||||
]
|
||||
"""每日宜忌数据"""
|
||||
|
||||
hour_taboo: List[str] = [
|
||||
'0F520120,6D61;0F7082520115000255,80262F;707A000855,0102;0100380806,707A2E2C;0F8252150255,70717A7D01002C0306;0F707A0120002C0855,87;,87;0F71822952202C,7A7D0102;0F70825201150255,2E2C;0F295220380255,707A01000306;0F82295201200255,70717A7D2C;0F707A0120002C0855,80262F;707A000855,0102;0F708252150255,2E01002C0806;0F522055,707A01000306;0F700120002C380855,;0F825201150255,70717A7D802C262F;0F70718229527A202C55,0102;,87;0F702952200255,7A7D01000306;0F7082527A01150255,;0F70012000380255,80262F;000855,70717A7D012C02;0F7071527A2055,2E2C;0F522055,707A01000306;0F7001200255,;0F7071297A0115202C55,80262F;0F71822952002C380806,707A0102;0F70825201150255,7A2E2C;0F200255,707A01000306;,87;0F700120002C0855,7A7D80262F;0F7082527A1555,0102;0100380806,2E2C;0F20190255,70717A7D01002C0306;0F707A0120002C0855,87;0F520120,707A6D80262F61;0F7082521555,0102;0F7071297A0115200255,2E2C;0F2952200255,707A01000306;0F825201150255,70717A7D2C;0F7001200255,80262F;,87;,7A2E7D2C;0F712915202C55,707A01000306;0F7029018020002C38,;0F825201150255,70717A7D802C262F;0F70718229527A202C55,0102;0F71822952012002,2E6D2C61;0F7029527A200255,01000806;0F71290115202C,707A55;01002C380806,707A80262F;0F8252150055,70717A7D012C02;0F715220,707A2E2C55;,87;0F7001200255,7A7D;0F825201150255,707A80262F;0F7182295220002C380806,707A010255;0F718229522002,707A2E2C55;0F2952200255,707A01000306',
|
||||
'0F700120000255,;0F70290120000855,6D61;0F707129527A15802C381955,01000806;0F7101200019020655,707A2C;0F200855,707A2E01002C0306;0F7182520115802C0255,707A;0F700120000255,;,87;0F70297A01202C380955,;0F8252150255,707A01002C0306;0F0120000855,707A2E2C;0F7071297A01158020002C0855,;0F7082520115000255,;0F70717A01201955,6D61;0F7071295215802C3855,01000806;0F0120000206,707A2C;0F290120000855,707A2E2C;0F7082527A0115202C0255,;0100380806,2E2C;,87;0F707129527A011580202C380255,;0F7082520115000255,;0F71202C1955,707A;0F707129527A1556802C1955,;0F202C4B,707A01000306;0F71201955,707A6D61;0F70202C55,01000806;0F0120000206,707A2C;0F7101201955,707A2E2C;0F7129521556802C0255,707A01000306;01002C380806,;,87;0F7129527A0115802C380255,;0F82520115000255,707A2C;0F202C0855,707A01000306;0F7129521556802C1955,707A;0F700120002C0855,;202C,6D61;0F71295215802C3802,01000806;0F2002,707A01002C0306;0F29012002,707A2E2C;0F708229527A0115202C0255,;01002C380806,;,87;0F71295215802C380855,707A01000306;0F82520115000255,707A;0F0120000855,707A2E2C;0F707129527A1556802C1955,;0F7082520115000255,;,707A01000306;0F707129527A15802C3855,01000806;0F290120000855,707A2C;0F71201955,707A2E2C;0F7182520115802C02,707A55;0F202C0855,707A01000306;,87;0F0120002C086C,707A55;0F82520115000255,707A2C;0F2901202C3809,707A55;0F7129521556802C196C,707A0100030655',
|
||||
'0F70297A0120000855,80262F;0F822952202C,0102;0F71822952012002,7A2E7D2C;0F712915202C55,707A01000306;0F718229520120002C380802066C,707A;707A01000855,80262F;0F7082527A1555,0102;0F7001200255,2E2C;,87;0F7071297A15202C55,01000806;0F7082527A0115000255,80262F;0F82521555,70717A7D012C02;0F70718229527A200255,2E01002C0806;0F52,0120002C080306;0F7182295201202C02,7A7D;0F708252150255,01800026082F06;0F7071297A20002C38080655,0102;0F0120000855,707A2E2C;0F708252150255,0120002C080306;0F822952202C02,01000806;,87;0F7071297A15202C55,0102;0F708252011500380255,2E2C;0F202C4B,01000806;0F71822952202C0255,707A;0F7082527A01150255,80262F;0F71822952202C,7A7D016D02;0F712915202C,01800026082F06;0F71292055,707A01000306;,707A01000806;0F7082527A0115000255,80262F;0F71822952202C,0102;,87;0F712915202C,707A01000306;0F825201150255,707A;0F70825201150255,80262F;0F70717A201955,0102;0F7001200255,2E2C;,707A01000306;0F7071297A15202C55,01000806;0F70297A012000380855,80262F;0F2920,70717A7D016D2C02;0F708252150255,2E01002C0806;,707A01000306;,87;0F7082527A01150255,2E2C;0F8252150038,707A010255;0F82520115000255,70717A7D2C;,707A01000306;0F5220,01000806;0F70297A0120000855,80262F;0F712915202C,016D000806;0F70718229527A01200038080206,2E2C;0F822952202C02,707A01000306;0F825201150255,707A;0F7082527A01150255,80262F;,87;0F7071297A011520002C55,;0F708252150255,01000806;0F8252150255,70717A7D01002C0806',
|
||||
'0F71822952202C02,707A;0F7029527A0120000255,;0F7071527A202C55,87;0F71295215802C3802,707A01000306;55,707A01000806;0F292055,707A2E2C;0F708229527A202C0255,01000806;0F708252150255,01000806;0F202C0855,707A01000306;,87;0F8229520115200255,707A2C;0F7082527A01150255,;0F7129521556802C1955,707A;2C3808,707A01000306;70297A0120002C0855,87;29202C,6D61;0F708229527A202C0255,01000806;0F71522055,707A2E01002C0806;0F7129521556802C0855,707A01000306;0F7082520115000255,;0F71290120002C080206,87;,87;0F0120004B,707A2C;0F8252150255,707A2E01002C0306;71295201155680002C0855,707A;0F70290120002C06,;0F822952202C0255,01000806;71295215802C38,01000806;0F7071822952202C0255,01000806;0F70718229520120002C080255,;0F70718229527A202C0255,;0F7082527A01150255,;0F70717A01200008190655,87;,87;0F8229520115200255,707A2C;0F708229527A0115202C0255,;0F707129527A011556802C026C,;2C38,01000806;0F202C0855,707A01000306;0F70712952011580202C380255,;0F718229522002,707A01002C0806;0F295201200255,707A2E2C;0F707129527A011556802C026C,;0F8252150255,707A01000306;0F70297A01202C0255,87;,87;0F8252150255,707A01002C0806;0F8252150255,707A2E01002C0806;0F712952155680202C0255,707A01000306;0F7029012000080255,;0F70718229527A202C0255,87;0F707129527A0180202C0255,;,707A01000806;0F822952202C02,707A01000306;707129527A01155680002C0855,;0F70822952011520002C0255,;0F822952202C02,01000806;,87;0F8252150255,707A01002C0306;0F82520115000255,707A2E2C',
|
||||
'0F82521555,70717A7D016D2C02;,2E2C;0F5220,707A01000306;0F0120000206,707A;0F825201150255,707A80262F;0F70717A202C381955,01000806;0F0120000206,70717A7D2C;0F7129202C1955,707A01000306;0F7082527A0115000255,;0F7082520115000255,80262F;,87;0F70717A0120003808190655,2E2C;0F8252150255,707A01000306;,2E2C;0F7082527A01150255,80262F;0F70200006,7A7D016D02;0F7071297A01152055,2E6D2C41;2C38,01000806;0F290120000855,70717A7D2C;0F70825201150255,80262F;0F702920002C,0102;0F0120004B,2E2C;,87;0F70717A0120002C3808190655,;0F7082520115000255,80262F;,0102;0F7071527A01200655,2E2C;0F702002,7A7D01000306;0F7129011520002C,6D41;0F70825215380255,01800026082F06;0F200006,70717A7D016D2C02;,2E2C;0F82521502,707A0100030655;0F7082520115000255,7A7D;,87;0F70717A20002C3808190655,016D02;0F825201150255,70717A7D2C;0F7129202C1955,707A01000306;0F520120006C,707A55;0F7082520115000255,7A7D80262F;0F712915202C,707A016D02;0F70717A20381955,2E01002C0806;0F29202C02,707A01000306;0F82295201202C02,707A;0F70825201150255,80262F;0F7082521555,7A7D016D02;,87;0F71202C38081955,707A01000306;0F82520115000255,70717A7D2C;0F70825201150255,80262F;0F70527A2055,016D02;0F0120000206,707A2E2C;0F712915202C,707A016D00034106;2C38,707A01000806;0F82520115000255,70717A7D802C262F;0F822952202C,0102;0F7082527A01150255,2E2C;0F708252150255,7A7D01000306;,87;01002C380806,80262F',
|
||||
'0F8229520102,707A202C03;0F7182520115802C0255,707A;0F29522055,707A01000306;0F70718229527A01202C0255,87;0F707129527A15803855,202C03;0F71822952200255,707A2C03;0F71822952012002,707A2E2C;0F7129521556802C0855,707A01000306;0F700120000255,;0F70010255,202C03;0F707129520115800038,202C03;,87;0F29522055,707A2E01002C0306;0F707182527A0115802C0255,;0F70297A55,202C03;0F7071297A0255,202C03;0F718229520120002C080206,;0F29200855,707A01000306;55,707A2E01002C0806;0F7071295201155680000855,202C03;0F01004B,202C03;0F825201150255,707A;0F7129521580202C3855,707A01000306;,87;0F70297A55,202C03;0F707182520115800255,202C03;0F7182295201002C38080206,;0F29200855,707A01000306;0F70297A202C02,01000806;0F70297A01000855,202C03;0F712920,707A2E01002C080306;0F7129521556802C55,707A;0F8252150255,707A01000306;0F8252011502,707A55;0F29526C,707A202C0355;,87;0F718229522002,707A2E2C;0F71825215802C0255,707A01000306;0F70202C55,01000806;0F707A01000855,202C03;0F707129520115800038,202C03;0F290180202C380955,707A6D61;0F7029527A2055,01000806;0F707129527A1556802C0255,;0F71520106,707A202C03;0F70825201150255,202C03;0F718229520120002C080206,;,87;0F200255,707A2E01002C0806;0F70718252011580000255,202C03;0F715201066C,707A202C03;0F290180202C380955,707A;0F71295215802C3855,707A01000306;0F70717A20190255,016D00086106;0F712952,0120002C080306;0F70718229527A0255,202C03;0F7182295201002C38080206,707A;0F8252150255,707A01000306;0F70202C55,01000806;,87',
|
||||
',87;0F822952200255,70717A7D01002C0306;0F70825201150255,87;0F7082527A01150255,2E2C;0F70202C55,7A7D0102;0F7029527A012055,2E2C;0F2920380855,707A01000306;0F82520115000255,70717A7D2C;0F7082527A01150255,80262F;0F52202C,016D02;0F70825201150255,7A2E7D2C;0F71822952202C0255,707A01000306;,87;0F825201150255,70717A7D802C262F;0F712952202C,0102;0F70527A012055,2E2C;700855,7A7D01000306;0F7071297A011520002C55,;0F8252011500380255,707A80262F;0F7082521555,010002;0F71290120,707A2E2C;0F71822952202C02,707A0100030655;0F7082527A01150255,;0F7001200255,2E2C;,87;0F707A01200255,2E2C;0F82521502,707A0100030655;0F0120002C086C,707A55;0F7082527A01150255,80262F;0F712915202C,016D02;0F2901203809,707A2E2C;0F708252150255,01000806;0F7182295201202C02,87;0F7082527A01150255,80262F;0F7082527A1555,0102;0F7071297A01152055,2E2C;,87;0F707A01200255,;0F70825201150255,80262F;0F52202C,016D02;0F71522055,707A2E2C;0F712915202C02,707A01000306;0F718229520120002C3802,6D41;0F7082527A150255,01800026082F06;0F71822952202C,0102;0F70527A012055,2E2C;0855,707A01000306;707A01000855,;,87;0F522055,70717A7D012C02;0F825201150255,707A2E2C;0F71822952202C02,707A01000306;0F707182295201202C0255,7A7D;0F7082527A01150255,80262F;0F71822952002C380806,016D0241;0F70200255,2E01002C0806;0855,707A01000306;0F700120002C0855,;0F70825201150255,7A7D80262F;0F712915202C,016D02',
|
||||
'0F290120002C0855,707A;,87;0F7071295201155680002C0206,;0F70822952011520002C0255,;0F70297A01202C0255,87;0F70712901158020002C380855,;0F8252150255,707A01000306;0F71201955,707A2E6D2C61;0F70297A0120002C0206,;0F710120002C3808190655,707A;0F290120002C0855,707A;0F71825215802C380255,707A01000306;,707A2E2C;,87;0F7071295201155680002C0855,;0F7082520115000255,;0F7120081955,707A01000306;0F7071295201158020002C380206,;0F0120004B,707A2C;0F71201955,707A;0F707129521556802C55,01000806;2C3808,707A0100030655;0F71201955,707A;0F70822952011520002C0255,;0F01200255,707A2C;,87;0F7129521556802C0855,707A01000306;0F70290120002C,;0F2901202C,87;0F71295201158020002C380206,707A;0F01200255,707A2C;0F71201955,707A2E016D002C036106;0F7129521556802C02,01000806;0F8229520120002C02,;0F70297A01202C0255,87;0F7082520115000255,;0F202C0855,707A01000306;,87;0F7071297A0120002C19020655,;0F82520115000255,707A;0F70297A01202C0255,87;0F71295215802C3802,707A01000306;0F825201150255,707A2C;0F71201955,707A2E2C;0F70712952155680202C0255,01000806;0F70290120000855,;0F202C0855,707A01000306;0F70718252011580002C380255,;0F7129202C1955,707A;,87;0F707129520115568020002C0255,;0F8252150255,707A01000306;0F70717A201955,2E2C;0F70290120002C0206,;0F01200255,707A2C;0F290120000855,707A2E6D2C61;0F707129521556802C55,01000806;01002C380806,;0F71201955,707A;0F718252011580002C380255,707A',
|
||||
'0F708252150255,01000806;0F707A010255,202C03;,87;2920002C0806,0102;0F7082527A01150255,2E2C;0F200255,707A01000306;0F7029527A0155,202C03;0F7082527A011500380255,80262F;0F82295220,70717A7D016D2C02;0F70717A201955,2E01002C0806;0F70527A2055,01000806;707A55,0120002C080306;0F70825201150255,80262F;002C380806,707A010255;,87;0F2002,707A0100030655;0F7029527A010255,202C03;0F0120002C4B02,80262F;0F7071297A15202C55,0102;0F70717A0120003808190655,2E2C;0F8229522002,70717A7D01002C0806;707A55,0120002C080306;0F7082527A01150255,80262F;29202C,7A7D016D02;0F7082520115000255,2E2C;0F71202C38081955,707A01000306;,87;0F70825201150255,80262F;0F7082521555,0102;0F7082527A01150255,2E2C;0F7071297A15202C55,01000806;0F700255,0120002C080306;0F825201150255,70717A7D6D802C262F61;,016D0002;0F70297A0120000855,2E2C;0F70200255,7A7D01000306;0F708229527A01150255,202C03;0F7082527A011500380255,80262F;,87;0F70717A201955,2E2C;0F708252150255,01000806;0F708252150255,0120002C080306;0F7082527A01150255,80262F;0F70717A2000381955,0102;0F290120000855,70717A7D2C;0F70202C55,01000806;0F70527A0155,202C03;0F70825201150255,7A7D80262F;0F7082521555,0102;0F70717A0120003808190655,2E2C;,87;0F7055,0120002C080306;0F70825201150255,80262F;0F7082521555,7A7D016D02;0F70297A0120000855,2E2C;0F71202C38081955,707A01000306;0F29522055,70717A7D2C03;0F708252150255,01800026082F06;0F522055,707A0102;0F71201955,707A2E2C',
|
||||
'71295215802C380855,707A01000306;0F825201150255,707A2C;0F822952011520000255,707A2E2C;,87;0F708252150255,01000806;0F8252150255,707A01000306;0F70718229527A202C0255,;0F292055,707A2C;0F82295201200255,707A2E2C;0F707129527A011556802C55,6D41;707A55,01000806;,707A55;0F70297A0120002C0855,;0F7082520115000255,;,707A2E01002C0806;,87;0F718229520120002C080206,;0F825201150255,707A;0F82295201202C02,707A55;,707A55;0855,707A2E01002C0306;0F707129527A1556802C55,6D41;0F7029202C55,01000806;0F700120002C0855,87;0F707129527A15802C3855,01000806;0F708252150255,01000806;0F71822952012002,707A2E2C;,87;0F7082520115000255,;0F825201150255,707A;71295215802C380855,707A01000306;,707A2C;0F0120000855,707A2E2C;0F7029012000080255,6D41;0F707152202C,01000806;0F71822952202C02,01000806;0F70718229527A01202C0255,;0F708229527A0115202C0255,;0F8229520120000255,707A2E2C;,87;0F8252150255,707A01000306;0F70825201150255,87;0F707A0120002C0855,;0F700120002C080255,;,707A2E01002C0806;0F71822952202C02,01000806;0F718229522C3802,01000806;0F2952202C55,707A;0F707129527A0115802C380255,;0F2901802000,707A2C;0855,707A2E01002C0306;,87;0F70822952011520002C0255,;0F7082520115000255,;0F707129527A15802C380255,01000806;0F718229522002,707A01002C0806;0F7182295201200002,707A2E2C;0F702901202C0255,6D41;2C38,01000806;0F7071297A2055,87',
|
||||
'0F7071201955,7A7D;0F71290115202C,707A80262F;0F70825215003855,016D02;0F825201150255,70717A7D2C;,87;0F520120,707A55;0F825201150255,707A80262F;0F71291520002C,016D02;0100380806,707A2E2C55;0F71201955,707A01000306;0F71295201202C,6D61;0F5220,01800026082F06;0F7071201955,7A7D016D02;0F7129011520,707A2E2C;2C3808,707A01000306;0F0120004B,70717A7D2C;,87;0F5220,016D02;0F70825201150255,7A2E7D2C;0F712915202C,707A01000306;0F70717A0120002C3808190655,;0F7082527A01150255,80262F;0F70200006,016D0261;0F5220,2E01002C0806;0F71201955,707A01000306;0F7129011520002C,707A;0F708252011500380255,80262F;0F82521555,70717A7D016D2C02;,87;0F5220,707A01000306;0F70825201150255,7A7D;0F825201150255,707A80262F;002C380806,016D02;0F201955,70717A7D2C;0F2002,707A016D00036106;0F5220,01000806;0F825201150255,707A80262F;0F71291520002C,016D02;0F708252011500380255,2E2C;0F8252150255,70717A7D01002C0306;,87;0F7082527A01150255,80262F;0F7082527A1555,016D02;0F7129011520,707A2E2C;2C3808,707A01000306;0F71201955,707A;0F7082520115000255,80262F;0F5220,016D0002;0F7071201955,7A2E7D2C;0F712915202C,707A01000306;0F7082527A011500380255,;0F825201150255,70717A7D802C262F;,87;0F7071520120002C06,;0F29202C55,707A01000306;0F7129011520002C,707A;0F8252011500380255,707A80262F;0F71201955,707A0102;0F700120000206,6D61;0F5220,01000806',
|
||||
'0F7182295201202C02,707A55;0F7029527A0120002C0255,;0F82520115000255,707A2C03;0F82520115000255,707A2E2C;0F7129521556802C1955,707A01000306;,87;0F7129202C196C,707A55;0F7182520115803802,707A202C0355;0F29522055,707A2C;0F71822952200255,707A2E01002C0306;0F718229520120002C080206,;0F290120000855,707A;0F700255,0120002C080306;707129527A011580002C380855,;0F204B,707A01002C0306;0F825201150255,707A;0F7071297A202C1955,;,87;0F707A01200255,87;0F71825215802C380255,707A01000306;0F7182295201202C02,;0F290120000855,707A2E2C;0F7071295201155680000855,202C03;01000855,707A;0F70717A201955,01000806;0F7129520115802C3855,707A;0F8229520115200255,707A2C;0F825201150255,707A2E2C03;0F707129527A1580202C55,;,87;0F70718229527A202C0255,87;0F70718252011580002C380255,;0F01200255,707A2C03;01000855,707A2E2C;0F7129521556802C1955,707A01000306;01002C380806,707A6D41;0F7071297A202C1955,01000806;0F707129527A15803855,202C03;0F01200255,707A2C;0F8252150255,707A01000306;0F71822952202C02,;,87;0F707A010255,202C03;707129527A011580002C380855,;0F29202C3809,707A01000306;0F71201955,707A;0F7071297A202C1955,;0100380806,6D202C0341;0F7029527A2055,01000806;0F71295215802C3855,707A01000306;0F825201150255,707A2C;0F822952011520000255,707A2E2C;0F7071295201155680000855,202C03;,87;0F29202C380955,707A01000306;0F7182520115802C380255,707A;29202C,707A;0F71292055,707A2E2C03;0F707129527A1556802C55,;0F71822952202C02,707A016D00034106'
|
||||
]
|
||||
"""时辰宜忌数据"""
|
||||
|
||||
def __init__(self, index_or_name: Union[int, str]):
|
||||
super().__init__(self.NAMES, index_or_name)
|
||||
|
||||
@classmethod
|
||||
def from_name(cls, name: str) -> Taboo:
|
||||
return cls(name)
|
||||
|
||||
@classmethod
|
||||
def from_index(cls, index: int) -> Taboo:
|
||||
return cls(index)
|
||||
|
||||
def next(self, n: int) -> Taboo:
|
||||
return Taboo(self.next_index(n))
|
||||
|
||||
@classmethod
|
||||
def _get_taboos(cls, data: List[str], sup_index: int, sub_index: int, index: int) -> List[Taboo]:
|
||||
l: List[Taboo] = []
|
||||
d: str = data[sup_index].split(';', -1)[sub_index].split(',', -1)[index]
|
||||
for i in range(0, d.__len__(), 2):
|
||||
l.append(Taboo(int(d[i:i + 2], 16)))
|
||||
return l
|
||||
|
||||
@classmethod
|
||||
def get_day_recommends(cls, month: SixtyCycle, day: SixtyCycle) -> List[Taboo]:
|
||||
"""
|
||||
日宜
|
||||
:param month: 月干支
|
||||
:param day: 日干支
|
||||
:return: 宜忌列表
|
||||
"""
|
||||
return Taboo._get_taboos(Taboo.day_taboo, month.get_earth_branch().get_index(), day.get_index(), 0)
|
||||
|
||||
@classmethod
|
||||
def get_day_avoids(cls, month: SixtyCycle, day: SixtyCycle) -> List[Taboo]:
|
||||
"""
|
||||
日忌
|
||||
:param month:月干支
|
||||
:param day: 日干支
|
||||
:return: 宜忌列表
|
||||
"""
|
||||
return Taboo._get_taboos(Taboo.day_taboo, month.get_earth_branch().get_index(), day.get_index(), 1)
|
||||
|
||||
@classmethod
|
||||
def get_hour_recommends(cls, day: SixtyCycle, hour: SixtyCycle) -> List[Taboo]:
|
||||
"""
|
||||
时辰宜
|
||||
:param day: 日干支
|
||||
:param hour: 时辰干支
|
||||
:return: 宜忌列表
|
||||
"""
|
||||
return Taboo._get_taboos(Taboo.hour_taboo, hour.get_earth_branch().get_index(), day.get_index(), 0)
|
||||
|
||||
@classmethod
|
||||
def get_hour_avoids(cls, day: SixtyCycle, hour: SixtyCycle) -> List[Taboo]:
|
||||
"""
|
||||
时辰忌
|
||||
:param day: 日干支
|
||||
:param hour:时辰干支
|
||||
:return: 宜忌列表
|
||||
"""
|
||||
return Taboo._get_taboos(Taboo.hour_taboo, hour.get_earth_branch().get_index(), day.get_index(), 1)
|
||||
|
||||
|
||||
class Ten(LoopTyme):
|
||||
"""旬"""
|
||||
NAMES: List[str] = ['甲子', '甲戌', '甲申', '甲午', '甲辰', '甲寅']
|
||||
"""名称"""
|
||||
|
||||
def __init__(self, index_or_name: Union[int, str]):
|
||||
super().__init__(self.NAMES, index_or_name)
|
||||
|
||||
@classmethod
|
||||
def from_name(cls, name: str) -> Ten:
|
||||
return cls(name)
|
||||
|
||||
@classmethod
|
||||
def from_index(cls, index: int) -> Ten:
|
||||
return cls(index)
|
||||
|
||||
def next(self, n: int):
|
||||
return Ten(self.next_index(n))
|
||||
|
||||
|
||||
class Terrain(LoopTyme):
|
||||
"""地势(长生十二神)"""
|
||||
NAMES: List[str] = ['长生', '沐浴', '冠带', '临官', '帝旺', '衰', '病', '死', '墓', '绝', '胎', '养']
|
||||
"""名称"""
|
||||
|
||||
def __init__(self, index_or_name: Union[int, str]):
|
||||
super().__init__(self.NAMES, index_or_name)
|
||||
|
||||
@classmethod
|
||||
def from_name(cls, name: str) -> Terrain:
|
||||
return cls(name)
|
||||
|
||||
@classmethod
|
||||
def from_index(cls, index: int) -> Terrain:
|
||||
return cls(index)
|
||||
|
||||
def next(self, n: int) -> Terrain:
|
||||
return Terrain(self.next_index(n))
|
||||
|
||||
|
||||
class Twenty(LoopTyme):
|
||||
"""运(20年=1运,3运=1元)"""
|
||||
NAMES: List[str] = ['一运', '二运', '三运', '四运', '五运', '六运', '七运', '八运', '九运']
|
||||
"""名称"""
|
||||
|
||||
def __init__(self, index_or_name: Union[int, str]):
|
||||
super().__init__(self.NAMES, index_or_name)
|
||||
|
||||
@classmethod
|
||||
def from_name(cls, name: str) -> Twenty:
|
||||
return cls(name)
|
||||
|
||||
@classmethod
|
||||
def from_index(cls, index: int) -> Twenty:
|
||||
return cls(index)
|
||||
|
||||
def next(self, n: int) -> Twenty:
|
||||
return Twenty(self.next_index(n))
|
||||
|
||||
def get_sixty(self) -> Sixty:
|
||||
"""
|
||||
元
|
||||
:return: 元
|
||||
"""
|
||||
return Sixty(self.get_index() // 3)
|
||||
|
||||
|
||||
class Week(LoopTyme):
|
||||
"""星期"""
|
||||
NAMES: List[str] = ['日', '一', '二', '三', '四', '五', '六']
|
||||
"""名称"""
|
||||
|
||||
def __init__(self, index_or_name: Union[int, str]):
|
||||
super().__init__(self.NAMES, index_or_name)
|
||||
|
||||
@classmethod
|
||||
def from_name(cls, name: str) -> Week:
|
||||
return cls(name)
|
||||
|
||||
@classmethod
|
||||
def from_index(cls, index: int) -> Week:
|
||||
return cls(index)
|
||||
|
||||
def next(self, n: int) -> Week:
|
||||
return Week(self.next_index(n))
|
||||
|
||||
def get_seven_star(self) -> SevenStar:
|
||||
"""
|
||||
七曜
|
||||
:return: 七曜
|
||||
"""
|
||||
from tyme4py.culture.star.seven import SevenStar
|
||||
return SevenStar(self.get_index())
|
||||
|
||||
|
||||
class Zodiac(LoopTyme):
|
||||
"""十二生肖"""
|
||||
NAMES: List[str] = ['鼠', '牛', '虎', '兔', '龙', '蛇', '马', '羊', '猴', '鸡', '狗', '猪']
|
||||
"""名称"""
|
||||
|
||||
def __init__(self, index_or_name: Union[int, str]):
|
||||
super().__init__(self.NAMES, index_or_name)
|
||||
|
||||
@classmethod
|
||||
def from_name(cls, name: str) -> Zodiac:
|
||||
return cls(name)
|
||||
|
||||
@classmethod
|
||||
def from_index(cls, index: int) -> Zodiac:
|
||||
return cls(index)
|
||||
|
||||
def next(self, n: int) -> Zodiac:
|
||||
return Zodiac(self.next_index(n))
|
||||
|
||||
def get_earth_branch(self) -> EarthBranch:
|
||||
"""
|
||||
地支
|
||||
:return: 地支
|
||||
"""
|
||||
from tyme4py.sixtycycle import EarthBranch
|
||||
return EarthBranch(self.get_index())
|
||||
|
||||
|
||||
class Zone(LoopTyme):
|
||||
"""宫"""
|
||||
NAMES: List[str] = ['东', '北', '西', '南']
|
||||
"""名称"""
|
||||
|
||||
def __init__(self, index_or_name: Union[int, str]):
|
||||
super().__init__(self.NAMES, index_or_name)
|
||||
|
||||
@classmethod
|
||||
def from_name(cls, name: str) -> Zone:
|
||||
return cls(name)
|
||||
|
||||
@classmethod
|
||||
def from_index(cls, index: int) -> Zone:
|
||||
return cls(index)
|
||||
|
||||
def next(self, n: int) -> Zone:
|
||||
return Zone(self.next_index(n))
|
||||
|
||||
def get_direction(self) -> Direction:
|
||||
"""
|
||||
方位
|
||||
:return: 方位
|
||||
"""
|
||||
return Direction(self.get_name())
|
||||
|
||||
def get_beast(self) -> Beast:
|
||||
"""
|
||||
神兽
|
||||
:return: 神兽
|
||||
"""
|
||||
return Beast(self.get_index())
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import List, Union
|
||||
|
||||
from tyme4py import LoopTyme, AbstractCultureDay
|
||||
|
||||
|
||||
class Dog(LoopTyme):
|
||||
"""三伏"""
|
||||
NAMES: List[str] = ['初伏', '中伏', '末伏']
|
||||
"""名称"""
|
||||
|
||||
def __init__(self, index_or_name: Union[int, str]):
|
||||
super().__init__(self.NAMES, index_or_name)
|
||||
|
||||
@classmethod
|
||||
def from_name(cls, name: str) -> Dog:
|
||||
return cls(name)
|
||||
|
||||
@classmethod
|
||||
def from_index(cls, index: int) -> Dog:
|
||||
return cls(index)
|
||||
|
||||
def next(self, n: int) -> Dog:
|
||||
return Dog(self.next_index(n))
|
||||
|
||||
|
||||
class DogDay(AbstractCultureDay):
|
||||
"""三伏天"""
|
||||
|
||||
def __init__(self, dog: Dog, day_index: int):
|
||||
super().__init__(dog, day_index)
|
||||
|
||||
def get_dog(self) -> Dog:
|
||||
"""
|
||||
三伏
|
||||
:return: 三伏
|
||||
"""
|
||||
return self.get_culture()
|
||||
+149
@@ -0,0 +1,149 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING, Union, List
|
||||
|
||||
from tyme4py import LoopTyme, AbstractCulture
|
||||
from tyme4py.culture import Direction
|
||||
from tyme4py.enums import Side
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from tyme4py.lunar import LunarDay, LunarMonth
|
||||
from tyme4py.sixtycycle import SixtyCycle, SixtyCycleDay
|
||||
|
||||
|
||||
class FetusEarthBranch(LoopTyme):
|
||||
"""地支六甲胎神"""
|
||||
NAMES: List[str] = ['碓', '厕', '炉', '门', '栖', '床']
|
||||
"""名称"""
|
||||
|
||||
def __init__(self, index_or_name: Union[int, str]):
|
||||
super().__init__(self.NAMES, index_or_name)
|
||||
|
||||
@classmethod
|
||||
def from_name(cls, name: str) -> FetusEarthBranch:
|
||||
return cls(name)
|
||||
|
||||
@classmethod
|
||||
def from_index(cls, index: int) -> FetusEarthBranch:
|
||||
return cls(index)
|
||||
|
||||
def next(self, n: int):
|
||||
return FetusEarthBranch(self.next_index(n))
|
||||
|
||||
|
||||
class FetusHeavenStem(LoopTyme):
|
||||
"""天干六甲胎神"""
|
||||
NAMES: List[str] = ['门', '碓磨', '厨灶', '仓库', '房床']
|
||||
"""名称"""
|
||||
|
||||
def __init__(self, index_or_name: Union[int, str]):
|
||||
super().__init__(self.NAMES, index_or_name)
|
||||
|
||||
@classmethod
|
||||
def from_name(cls, name: str) -> FetusHeavenStem:
|
||||
return cls(name)
|
||||
|
||||
@classmethod
|
||||
def from_index(cls, index: int) -> FetusHeavenStem:
|
||||
return cls(index)
|
||||
|
||||
def next(self, n: int) -> FetusHeavenStem:
|
||||
return FetusHeavenStem(self.next_index(n))
|
||||
|
||||
|
||||
class FetusMonth(LoopTyme):
|
||||
"""逐月胎神"""
|
||||
NAMES: List[str] = ['占房床', '占户窗', '占门堂', '占厨灶', '占房床', '占床仓', '占碓磨', '占厕户', '占门房', '占房床', '占灶炉', '占房床']
|
||||
"""名称"""
|
||||
|
||||
def __init__(self, index_or_name: Union[int, str]):
|
||||
super().__init__(self.NAMES, index_or_name)
|
||||
|
||||
@classmethod
|
||||
def from_name(cls, name: str) -> FetusMonth:
|
||||
return cls(name)
|
||||
|
||||
@classmethod
|
||||
def from_index(cls, index: int) -> FetusMonth:
|
||||
return cls(index)
|
||||
|
||||
@classmethod
|
||||
def from_lunar_month(cls, lunar_month: LunarMonth) -> Union[FetusMonth, None]:
|
||||
"""
|
||||
从农历月初始化
|
||||
:param lunar_month: 农历月
|
||||
:return: 逐月胎神
|
||||
"""
|
||||
return None if lunar_month.is_leap() else cls(lunar_month.get_month() - 1)
|
||||
|
||||
def next(self, n: int) -> FetusMonth:
|
||||
return FetusMonth(self.next_index(n))
|
||||
|
||||
|
||||
class FetusDay(AbstractCulture):
|
||||
"""逐日胎神"""
|
||||
|
||||
def __init__(self, sixty_cycle: SixtyCycle):
|
||||
self._fetus_heaven_stem = FetusHeavenStem(sixty_cycle.get_heaven_stem().get_index() % 5)
|
||||
self._fetus_earth_branch = FetusEarthBranch(sixty_cycle.get_earth_branch().get_index() % 6)
|
||||
index: int = [3, 3, 8, 8, 8, 8, 8, 1, 1, 1, 1, 1, 1, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, -9, -9, -9, -9, -9, -5, -5, -1, -1, -1, -3, -7, -7, -7, -7, -5, 7, 7, 7, 7, 7, 7, 2, 2, 2, 2, 2, 3, 3, 3, 3][sixty_cycle.get_index()]
|
||||
self._side = Side.IN if index < 0 else Side.OUT
|
||||
self._direction = Direction(index)
|
||||
|
||||
@classmethod
|
||||
def from_lunar_day(cls, lunar_day: LunarDay) -> FetusDay:
|
||||
return cls(lunar_day.get_sixty_cycle())
|
||||
|
||||
@classmethod
|
||||
def from_sixty_cycle_day(cls, sixty_cycle_day: SixtyCycleDay) -> FetusDay:
|
||||
return cls(sixty_cycle_day.get_sixty_cycle())
|
||||
|
||||
def get_name(self) -> str:
|
||||
s: str = self._fetus_heaven_stem.get_name() + self._fetus_earth_branch.get_name()
|
||||
if '门门' == s:
|
||||
s = '占大门'
|
||||
elif '碓磨碓' == s:
|
||||
s = '占碓磨'
|
||||
elif '房床床' == s:
|
||||
s = '占房床'
|
||||
elif s.startswith('门'):
|
||||
s = '占' + s
|
||||
s += ' '
|
||||
if Side.IN == self._side:
|
||||
s += '房内'
|
||||
else:
|
||||
s += '外'
|
||||
direction_name: str = self._direction.get_name()
|
||||
if Side.OUT == self._side and '北南西东'.find(direction_name) != -1:
|
||||
s += '正'
|
||||
s += direction_name
|
||||
return s
|
||||
|
||||
def get_side(self) -> Side:
|
||||
"""
|
||||
内外
|
||||
:return: 内外
|
||||
"""
|
||||
return self._side
|
||||
|
||||
def get_direction(self) -> Direction:
|
||||
"""
|
||||
方位
|
||||
:return: 方位
|
||||
"""
|
||||
return self._direction
|
||||
|
||||
def get_fetus_heaven_stem(self) -> FetusHeavenStem:
|
||||
"""
|
||||
天干六甲胎神
|
||||
:return: 天干六甲胎神
|
||||
"""
|
||||
return self._fetus_heaven_stem
|
||||
|
||||
def get_fetus_earth_branch(self) -> FetusEarthBranch:
|
||||
"""
|
||||
地支六甲胎神
|
||||
:return: 地支六甲胎神
|
||||
"""
|
||||
return self._fetus_earth_branch
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Union, List
|
||||
|
||||
from tyme4py import LoopTyme, AbstractCultureDay
|
||||
|
||||
|
||||
class Nine(LoopTyme):
|
||||
"""数九"""
|
||||
NAMES: List[str] = ['一九', '二九', '三九', '四九', '五九', '六九', '七九', '八九', '九九']
|
||||
"""名称"""
|
||||
|
||||
def __init__(self, index_or_name: Union[int, str]):
|
||||
super().__init__(self.NAMES, index_or_name)
|
||||
|
||||
@classmethod
|
||||
def from_name(cls, name: str) -> Nine:
|
||||
return cls(name)
|
||||
|
||||
@classmethod
|
||||
def from_index(cls, index: int) -> Nine:
|
||||
return cls(index)
|
||||
|
||||
def next(self, n: int):
|
||||
return Nine(self.next_index(n))
|
||||
|
||||
|
||||
class NineDay(AbstractCultureDay):
|
||||
"""数九天"""
|
||||
|
||||
def __init__(self, nine: Nine, day_index: int):
|
||||
super().__init__(nine, day_index)
|
||||
|
||||
def get_nine(self) -> Nine:
|
||||
"""
|
||||
数九
|
||||
:return: 数九
|
||||
"""
|
||||
return self.get_culture()
|
||||
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING, List, Union
|
||||
|
||||
from tyme4py import LoopTyme, AbstractCulture
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from tyme4py.sixtycycle import SixtyCycle
|
||||
|
||||
|
||||
class PengZuEarthBranch(LoopTyme):
|
||||
"""地支彭祖百忌"""
|
||||
NAMES: List[str] = ['子不问卜自惹祸殃', '丑不冠带主不还乡', '寅不祭祀神鬼不尝', '卯不穿井水泉不香', '辰不哭泣必主重丧', '巳不远行财物伏藏', '午不苫盖屋主更张', '未不服药毒气入肠', '申不安床鬼祟入房', '酉不会客醉坐颠狂', '戌不吃犬作怪上床', '亥不嫁娶不利新郎']
|
||||
"""名称"""
|
||||
|
||||
def __init__(self, index_or_name: Union[int, str]):
|
||||
super().__init__(self.NAMES, index_or_name)
|
||||
|
||||
@classmethod
|
||||
def from_name(cls, name: str) -> PengZuEarthBranch:
|
||||
return cls(name)
|
||||
|
||||
@classmethod
|
||||
def from_index(cls, index: int) -> PengZuEarthBranch:
|
||||
return cls(index)
|
||||
|
||||
def next(self, n: int):
|
||||
return PengZuEarthBranch(self.next_index(n))
|
||||
|
||||
|
||||
class PengZuHeavenStem(LoopTyme):
|
||||
"""天干彭祖百忌"""
|
||||
NAMES: List[str] = ['甲不开仓财物耗散', '乙不栽植千株不长', '丙不修灶必见灾殃', '丁不剃头头必生疮', '戊不受田田主不祥', '己不破券二比并亡', '庚不经络织机虚张', '辛不合酱主人不尝', '壬不泱水更难提防', '癸不词讼理弱敌强']
|
||||
"""名称"""
|
||||
|
||||
def __init__(self, index_or_name: Union[int, str]):
|
||||
super().__init__(self.NAMES, index_or_name)
|
||||
|
||||
@classmethod
|
||||
def from_name(cls, name: str) -> PengZuHeavenStem:
|
||||
return cls(name)
|
||||
|
||||
@classmethod
|
||||
def from_index(cls, index: int) -> PengZuHeavenStem:
|
||||
return cls(index)
|
||||
|
||||
def next(self, n: int) -> PengZuHeavenStem:
|
||||
return PengZuHeavenStem(self.next_index(n))
|
||||
|
||||
|
||||
class PengZu(AbstractCulture):
|
||||
"""彭祖百忌"""
|
||||
|
||||
def __init__(self, sixty_cycle: SixtyCycle):
|
||||
self._peng_zu_heaven_stem = PengZuHeavenStem(sixty_cycle.get_heaven_stem().get_index())
|
||||
self._peng_zu_earth_branch = PengZuEarthBranch(sixty_cycle.get_earth_branch().get_index())
|
||||
|
||||
@classmethod
|
||||
def from_sixty_cycle(cls, sixty_cycle: SixtyCycle) -> PengZu:
|
||||
return cls(sixty_cycle)
|
||||
|
||||
def get_name(self) -> str:
|
||||
return self._peng_zu_heaven_stem.get_name() + " " + self._peng_zu_earth_branch.get_name()
|
||||
|
||||
def get_peng_zu_heaven_stem(self) -> PengZuHeavenStem:
|
||||
"""
|
||||
天干彭祖百忌
|
||||
:return: 天干彭祖百忌
|
||||
"""
|
||||
return self._peng_zu_heaven_stem
|
||||
|
||||
def get_peng_zu_earth_branch(self) -> PengZuEarthBranch:
|
||||
"""
|
||||
地支彭祖百忌
|
||||
:return: 地支彭祖百忌
|
||||
"""
|
||||
return self._peng_zu_earth_branch
|
||||
+87
@@ -0,0 +1,87 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import List, Union
|
||||
|
||||
from tyme4py import LoopTyme, AbstractCultureDay
|
||||
from tyme4py.jd import JulianDay
|
||||
from tyme4py.util import ShouXingUtil
|
||||
|
||||
|
||||
class Phenology(LoopTyme):
|
||||
"""候"""
|
||||
NAMES: List[str] = ['蚯蚓结', '麋角解', '水泉动', '雁北乡', '鹊始巢', '雉始雊', '鸡始乳', '征鸟厉疾', '水泽腹坚', '东风解冻', '蛰虫始振', '鱼陟负冰', '獭祭鱼', '候雁北', '草木萌动', '桃始华', '仓庚鸣', '鹰化为鸠', '玄鸟至', '雷乃发声', '始电', '桐始华', '田鼠化为鴽', '虹始见', '萍始生', '鸣鸠拂其羽', '戴胜降于桑', '蝼蝈鸣', '蚯蚓出', '王瓜生', '苦菜秀', '靡草死', '麦秋至', '螳螂生', '鵙始鸣', '反舌无声', '鹿角解', '蜩始鸣', '半夏生', '温风至', '蟋蟀居壁', '鹰始挚', '腐草为萤', '土润溽暑', '大雨行时', '凉风至', '白露降', '寒蝉鸣', '鹰乃祭鸟', '天地始肃', '禾乃登', '鸿雁来', '玄鸟归', '群鸟养羞', '雷始收声', '蛰虫坯户', '水始涸', '鸿雁来宾', '雀入大水为蛤', '菊有黄花', '豺乃祭兽', '草木黄落', '蛰虫咸俯', '水始冰', '地始冻', '雉入大水为蜃', '虹藏不见', '天气上升地气下降', '闭塞而成冬', '鹖鴠不鸣', '虎始交', '荔挺出']
|
||||
"""名称"""
|
||||
|
||||
def __init__(self, year: int, index_or_name: Union[int, str]):
|
||||
super().__init__(self.NAMES, index_or_name)
|
||||
if isinstance(index_or_name, int):
|
||||
size: int = self.get_size()
|
||||
self._year = (year * size + index_or_name) // size
|
||||
else:
|
||||
self._year = year
|
||||
|
||||
@classmethod
|
||||
def from_name(cls, year: int, name: str) -> Phenology:
|
||||
return cls(year, name)
|
||||
|
||||
@classmethod
|
||||
def from_index(cls, year: int, index: int) -> Phenology:
|
||||
return cls(year, index)
|
||||
|
||||
def next(self, n: int) -> Phenology:
|
||||
size: int = self.get_size()
|
||||
i: int = self.get_index() + n
|
||||
return Phenology((self.get_year() * size + i) // size, self.index_of(i, size))
|
||||
|
||||
def get_year(self) -> int:
|
||||
"""
|
||||
:return: 年
|
||||
"""
|
||||
return self._year
|
||||
|
||||
def get_three_phenology(self) -> ThreePhenology:
|
||||
"""
|
||||
:return: 三候
|
||||
"""
|
||||
return ThreePhenology(self.get_index() % 3)
|
||||
|
||||
def get_julian_day(self) -> JulianDay:
|
||||
"""
|
||||
:return: 儒略日
|
||||
"""
|
||||
t = ShouXingUtil.sa_lon_t((self.get_year() - 2000 + (self.get_index() - 18) * 5.0 / 360 + 1) * 2 * ShouXingUtil.PI)
|
||||
return JulianDay.from_julian_day(t * 36525 + JulianDay.J2000 + 8.0 / 24 - ShouXingUtil.dt_t(t * 36525))
|
||||
|
||||
|
||||
class ThreePhenology(LoopTyme):
|
||||
"""三候"""
|
||||
NAMES: List[str] = ['初候', '二候', '三候']
|
||||
"""名称"""
|
||||
|
||||
def __init__(self, index_or_name: Union[int, str]):
|
||||
super().__init__(self.NAMES, index_or_name)
|
||||
|
||||
@classmethod
|
||||
def from_name(cls, name: str) -> ThreePhenology:
|
||||
return cls(name)
|
||||
|
||||
@classmethod
|
||||
def from_index(cls, index: int) -> ThreePhenology:
|
||||
return cls(index)
|
||||
|
||||
def next(self, n: int) -> ThreePhenology:
|
||||
return ThreePhenology(self.next_index(n))
|
||||
|
||||
def get_three_phenology(self) -> ThreePhenology:
|
||||
return ThreePhenology(self.get_index() % 3)
|
||||
|
||||
|
||||
class PhenologyDay(AbstractCultureDay):
|
||||
"""七十二候"""
|
||||
|
||||
def __init__(self, phenology: Phenology, day_index: int):
|
||||
super().__init__(phenology, day_index)
|
||||
|
||||
def get_phenology(self) -> Phenology:
|
||||
return super().get_culture()
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import List, Union
|
||||
|
||||
from tyme4py import LoopTyme, AbstractCultureDay
|
||||
|
||||
|
||||
class PlumRain(LoopTyme):
|
||||
"""梅雨"""
|
||||
NAMES: List[str] = ['入梅', '出梅']
|
||||
"""名称"""
|
||||
|
||||
def __init__(self, index_or_name: Union[int, str]):
|
||||
super().__init__(self.NAMES, index_or_name)
|
||||
|
||||
@classmethod
|
||||
def from_name(cls, name: str) -> PlumRain:
|
||||
return cls(name)
|
||||
|
||||
@classmethod
|
||||
def from_index(cls, index: int) -> PlumRain:
|
||||
return cls(index)
|
||||
|
||||
def next(self, n: int) -> PlumRain:
|
||||
return PlumRain(self.next_index(n))
|
||||
|
||||
|
||||
class PlumRainDay(AbstractCultureDay):
|
||||
"""梅雨天"""
|
||||
|
||||
def __init__(self, plum_rain: PlumRain, day_index: int):
|
||||
super().__init__(plum_rain, day_index)
|
||||
|
||||
def get_plum_rain(self) -> PlumRain:
|
||||
"""
|
||||
梅雨
|
||||
:return: 梅雨
|
||||
"""
|
||||
return super().get_culture()
|
||||
|
||||
def __str__(self) -> str:
|
||||
return super().__str__() if self.get_plum_rain().get_index() == 0 else self.get_plum_rain().get_name()
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import List, Union
|
||||
|
||||
from tyme4py import LoopTyme
|
||||
from tyme4py.culture import Luck, Element
|
||||
|
||||
|
||||
class MinorRen(LoopTyme):
|
||||
"""小六壬"""
|
||||
NAMES: List[str] = ['大安', '留连', '速喜', '赤口', '小吉', '空亡']
|
||||
"""名称"""
|
||||
|
||||
def __init__(self, index_or_name: Union[int, str]):
|
||||
super().__init__(self.NAMES, index_or_name)
|
||||
|
||||
def next(self, n: int) -> MinorRen:
|
||||
return MinorRen(self.next_index(n))
|
||||
|
||||
def get_luck(self) -> Luck:
|
||||
"""
|
||||
吉凶
|
||||
:return: 吉凶
|
||||
"""
|
||||
return Luck(self.get_index() % 2)
|
||||
|
||||
def get_element(self) -> Element:
|
||||
"""
|
||||
五行
|
||||
:return: 五行
|
||||
"""
|
||||
return Element([0, 4, 1, 3, 0, 2][self.get_index()])
|
||||
+1
@@ -0,0 +1 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
Vendored
+80
@@ -0,0 +1,80 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import List, Union
|
||||
|
||||
from tyme4py import LoopTyme
|
||||
from tyme4py.culture import Direction, Element
|
||||
|
||||
|
||||
class Dipper(LoopTyme):
|
||||
"""北斗九星"""
|
||||
NAMES: List[str] = ['天枢', '天璇', '天玑', '天权', '玉衡', '开阳', '摇光', '洞明', '隐元']
|
||||
"""名称"""
|
||||
|
||||
def __init__(self, index_or_name: Union[int, str]):
|
||||
super().__init__(self.NAMES, index_or_name)
|
||||
|
||||
@classmethod
|
||||
def from_name(cls, name: str) -> Dipper:
|
||||
return cls(name)
|
||||
|
||||
@classmethod
|
||||
def from_index(cls, index: int) -> Dipper:
|
||||
return cls(index)
|
||||
|
||||
def next(self, n: int) -> Dipper:
|
||||
return Dipper(self.next_index(n))
|
||||
|
||||
|
||||
class NineStar(LoopTyme):
|
||||
"""九星"""
|
||||
NAMES: List[str] = ['一', '二', '三', '四', '五', '六', '七', '八', '九']
|
||||
"""名称"""
|
||||
COLORS: List[str] = ['白', '黑', '碧', '绿', '黄', '白', '赤', '白', '紫']
|
||||
"""颜色"""
|
||||
|
||||
def __init__(self, index_or_name: Union[int, str]):
|
||||
super().__init__(self.NAMES, index_or_name)
|
||||
|
||||
@classmethod
|
||||
def from_name(cls, name: str) -> NineStar:
|
||||
return cls(name)
|
||||
|
||||
@classmethod
|
||||
def from_index(cls, index: int) -> NineStar:
|
||||
return cls(index)
|
||||
|
||||
def next(self, n: int) -> NineStar:
|
||||
return NineStar(self.next_index(n))
|
||||
|
||||
def get_color(self) -> str:
|
||||
"""
|
||||
颜色
|
||||
:return: 颜色
|
||||
"""
|
||||
return self.COLORS[self.get_index()]
|
||||
|
||||
def get_element(self) -> Element:
|
||||
"""
|
||||
五行
|
||||
:return: 五行
|
||||
"""
|
||||
return self.get_direction().get_element()
|
||||
|
||||
def get_dipper(self) -> Dipper:
|
||||
"""
|
||||
北斗九星
|
||||
:return: 北斗九星
|
||||
"""
|
||||
return Dipper(self.get_index())
|
||||
|
||||
def get_direction(self) -> Direction:
|
||||
"""
|
||||
方位
|
||||
:return: 方位
|
||||
"""
|
||||
return Direction(self.get_index())
|
||||
|
||||
def __str__(self) -> str:
|
||||
return f'{self.get_name()}{self.get_color()}{self.get_element().get_name()}'
|
||||
Vendored
+33
@@ -0,0 +1,33 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import List, Union
|
||||
|
||||
from tyme4py import LoopTyme
|
||||
from tyme4py.culture import Week
|
||||
|
||||
|
||||
class SevenStar(LoopTyme):
|
||||
"""七曜(七政、七纬、七耀)"""
|
||||
NAMES: List[str] = ['日', '月', '火', '水', '木', '金', '土']
|
||||
"""名称"""
|
||||
|
||||
def __init__(self, index_or_name: Union[int, str]):
|
||||
super().__init__(self.NAMES, index_or_name)
|
||||
|
||||
@classmethod
|
||||
def from_name(cls, name: str) -> SevenStar:
|
||||
return cls(name)
|
||||
|
||||
@classmethod
|
||||
def from_index(cls, index: int) -> SevenStar:
|
||||
return cls(index)
|
||||
|
||||
def next(self, n: int) -> SevenStar:
|
||||
return SevenStar(super().next_index(n))
|
||||
|
||||
def get_week(self) -> Week:
|
||||
"""
|
||||
:return:星期
|
||||
"""
|
||||
return Week(self.get_index())
|
||||
Vendored
+26
@@ -0,0 +1,26 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import List, Union
|
||||
|
||||
from tyme4py import LoopTyme
|
||||
|
||||
|
||||
class SixStar(LoopTyme):
|
||||
"""六曜"""
|
||||
NAMES: List[str] = ['先胜', '友引', '先负', '佛灭', '大安', '赤口']
|
||||
"""名称"""
|
||||
|
||||
def __init__(self, index_or_name: Union[int, str]):
|
||||
super().__init__(self.NAMES, index_or_name)
|
||||
|
||||
@classmethod
|
||||
def from_name(cls, name: str) -> SixStar:
|
||||
return cls(name)
|
||||
|
||||
@classmethod
|
||||
def from_index(cls, index: int) -> SixStar:
|
||||
return cls(index)
|
||||
|
||||
def next(self, n: int) -> SixStar:
|
||||
return SixStar(self.next_index(n))
|
||||
Vendored
+26
@@ -0,0 +1,26 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import List, Union
|
||||
|
||||
from tyme4py import LoopTyme
|
||||
|
||||
|
||||
class TenStar(LoopTyme):
|
||||
"""十神"""
|
||||
NAMES: List[str] = ['比肩', '劫财', '食神', '伤官', '偏财', '正财', '七杀', '正官', '偏印', '正印']
|
||||
"""名称"""
|
||||
|
||||
def __init__(self, index_or_name: Union[int, str]):
|
||||
super().__init__(self.NAMES, index_or_name)
|
||||
|
||||
@classmethod
|
||||
def from_name(cls, name: str) -> TenStar:
|
||||
return cls(name)
|
||||
|
||||
@classmethod
|
||||
def from_index(cls, index: int) -> TenStar:
|
||||
return cls(index)
|
||||
|
||||
def next(self, n: int) -> TenStar:
|
||||
return TenStar(self.next_index(n))
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import List, Union
|
||||
|
||||
from tyme4py import LoopTyme
|
||||
from tyme4py.culture import Luck
|
||||
|
||||
|
||||
class TwelveStar(LoopTyme):
|
||||
"""黄道黑道十二神"""
|
||||
NAMES: List[str] = ['青龙', '明堂', '天刑', '朱雀', '金匮', '天德', '白虎', '玉堂', '天牢', '玄武', '司命', '勾陈']
|
||||
"""名称"""
|
||||
|
||||
def __init__(self, index_or_name: Union[int, str]):
|
||||
super().__init__(self.NAMES, index_or_name)
|
||||
|
||||
@classmethod
|
||||
def from_name(cls, name: str) -> TwelveStar:
|
||||
return cls(name)
|
||||
|
||||
@classmethod
|
||||
def from_index(cls, index: int) -> TwelveStar:
|
||||
return cls(index)
|
||||
|
||||
def next(self, n: int) -> TwelveStar:
|
||||
return TwelveStar(self.next_index(n))
|
||||
|
||||
def get_ecliptic(self) -> Ecliptic:
|
||||
"""
|
||||
黄道黑道
|
||||
:return: 黄道黑道
|
||||
"""
|
||||
return Ecliptic([0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1][self.get_index()])
|
||||
|
||||
|
||||
class Ecliptic(LoopTyme):
|
||||
"""黄道黑道就两种,依次为:黄道、黑道。"""
|
||||
NAMES: List[str] = ["黄道", "黑道"]
|
||||
"""名称"""
|
||||
|
||||
def __init__(self, index_or_name: Union[int, str]):
|
||||
super().__init__(self.NAMES, index_or_name)
|
||||
|
||||
@classmethod
|
||||
def from_name(cls, name: str) -> Ecliptic:
|
||||
return cls(name)
|
||||
|
||||
@classmethod
|
||||
def from_index(cls, index: int) -> Ecliptic:
|
||||
return cls(index)
|
||||
|
||||
def next(self, n: int) -> Ecliptic:
|
||||
return Ecliptic(self.next_index(n))
|
||||
|
||||
def get_luck(self) -> Luck:
|
||||
"""
|
||||
吉凶
|
||||
:return: 吉凶
|
||||
"""
|
||||
return Luck(self.get_index())
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING, List, Union
|
||||
|
||||
from tyme4py import LoopTyme
|
||||
from tyme4py.culture import Land, Animal, Luck, Zone
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from tyme4py.culture.star.seven import SevenStar
|
||||
|
||||
|
||||
class TwentyEightStar(LoopTyme):
|
||||
"""二十八宿"""
|
||||
NAMES: List[str] = ['角', '亢', '氐', '房', '心', '尾', '箕', '斗', '牛', '女', '虚', '危', '室', '壁', '奎', '娄', '胃', '昴', '毕', '觜', '参', '井', '鬼', '柳', '星', '张', '翼', '轸']
|
||||
"""名称"""
|
||||
|
||||
def __init__(self, index_or_name: Union[int, str]):
|
||||
super().__init__(self.NAMES, index_or_name)
|
||||
|
||||
@classmethod
|
||||
def from_name(cls, name: str) -> TwentyEightStar:
|
||||
return cls(name)
|
||||
|
||||
@classmethod
|
||||
def from_index(cls, index: int) -> TwentyEightStar:
|
||||
return cls(index)
|
||||
|
||||
def next(self, n: int) -> TwentyEightStar:
|
||||
return TwentyEightStar(self.next_index(n))
|
||||
|
||||
def get_seven_star(self) -> SevenStar:
|
||||
"""
|
||||
:return: 七曜
|
||||
"""
|
||||
from tyme4py.culture.star.seven import SevenStar
|
||||
return SevenStar(self.get_index() % 7 + 4)
|
||||
|
||||
def get_land(self) -> Land:
|
||||
"""
|
||||
:return: 九野
|
||||
"""
|
||||
return Land([4, 4, 4, 2, 2, 2, 7, 7, 7, 0, 0, 0, 0, 5, 5, 5, 6, 6, 6, 1, 1, 1, 8, 8, 8, 3, 3, 3][self.get_index()])
|
||||
|
||||
def get_zone(self) -> Zone:
|
||||
"""
|
||||
:return: 宫
|
||||
"""
|
||||
return Zone(self.get_index() // 7)
|
||||
|
||||
def get_animal(self) -> Animal:
|
||||
"""
|
||||
:return: 动物
|
||||
"""
|
||||
return Animal(self.get_index())
|
||||
|
||||
def get_luck(self) -> Luck:
|
||||
"""
|
||||
:return: 吉凶
|
||||
"""
|
||||
return Luck([0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0][self.get_index()])
|
||||
Vendored
+501
@@ -0,0 +1,501 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
from __future__ import annotations
|
||||
|
||||
import warnings
|
||||
from math import ceil
|
||||
from typing import TYPE_CHECKING, Union, List
|
||||
|
||||
from tyme4py import AbstractCulture, AbstractTyme
|
||||
from tyme4py.culture import Duty
|
||||
from tyme4py.eightchar.provider import ChildLimitProvider
|
||||
from tyme4py.eightchar.provider.impl import DefaultChildLimitProvider
|
||||
from tyme4py.enums import Gender, YinYang
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from tyme4py.lunar import LunarYear
|
||||
from tyme4py.solar import SolarTime, SolarTerm, SolarDay
|
||||
from tyme4py.sixtycycle import SixtyCycle, SixtyCycleYear, ThreePillars
|
||||
|
||||
|
||||
class EightChar(AbstractCulture):
|
||||
"""八字"""
|
||||
|
||||
def __init__(self, year: Union[SixtyCycle, str], month: Union[SixtyCycle, str], day: Union[SixtyCycle, str], hour: Union[SixtyCycle, str]):
|
||||
"""
|
||||
初始化
|
||||
:param year: 年干支
|
||||
:param month: 月干支
|
||||
:param day: 日干支
|
||||
:param hour: 时干支
|
||||
"""
|
||||
from tyme4py.sixtycycle import SixtyCycle, ThreePillars
|
||||
self._three_pillars = ThreePillars(year if isinstance(year, SixtyCycle) else SixtyCycle(year), month if isinstance(month, SixtyCycle) else SixtyCycle(month), day if isinstance(day, SixtyCycle) else SixtyCycle(day))
|
||||
self._hour = hour if isinstance(hour, SixtyCycle) else SixtyCycle(hour)
|
||||
|
||||
def get_year(self) -> SixtyCycle:
|
||||
"""
|
||||
年柱
|
||||
:return: 干支 SixtyCycle
|
||||
"""
|
||||
return self._three_pillars.get_year()
|
||||
|
||||
def get_month(self) -> SixtyCycle:
|
||||
"""
|
||||
月柱
|
||||
:return: 干支 SixtyCycle
|
||||
"""
|
||||
return self._three_pillars.get_month()
|
||||
|
||||
def get_day(self) -> SixtyCycle:
|
||||
"""
|
||||
日柱
|
||||
:return: 干支 SixtyCycle
|
||||
"""
|
||||
return self._three_pillars.get_day()
|
||||
|
||||
def get_hour(self) -> SixtyCycle:
|
||||
"""
|
||||
时柱
|
||||
:return: 干支 SixtyCycle
|
||||
"""
|
||||
return self._hour
|
||||
|
||||
def get_fetal_origin(self) -> SixtyCycle:
|
||||
"""
|
||||
胎元
|
||||
:return: 干支 SixtyCycle
|
||||
"""
|
||||
from tyme4py.sixtycycle import SixtyCycle
|
||||
m: SixtyCycle = self.get_month()
|
||||
return SixtyCycle.from_index(m.get_heaven_stem().next(1).get_index() * 6 - m.get_earth_branch().next(3).get_index() * 5)
|
||||
|
||||
def get_fetal_breath(self) -> SixtyCycle:
|
||||
"""
|
||||
胎息
|
||||
:return: 干支 SixtyCycle
|
||||
"""
|
||||
from tyme4py.sixtycycle import SixtyCycle
|
||||
d: SixtyCycle = self.get_day()
|
||||
return SixtyCycle.from_index(d.get_heaven_stem().next(5).get_index() * 6 + d.get_earth_branch().get_index() * 5 - 65)
|
||||
|
||||
def get_own_sign(self) -> SixtyCycle:
|
||||
"""
|
||||
命宫
|
||||
:return: 干支 SixtyCycle
|
||||
"""
|
||||
from tyme4py.sixtycycle import SixtyCycle
|
||||
return SixtyCycle.from_index(self.get_year().get_heaven_stem().get_index() * 12 + (27 - self.get_month().get_earth_branch().get_index() - self._hour.get_earth_branch().get_index()) % 12 + 2)
|
||||
|
||||
def get_body_sign(self) -> SixtyCycle:
|
||||
"""
|
||||
身宫
|
||||
:return: 干支 SixtyCycle
|
||||
"""
|
||||
from tyme4py.sixtycycle import SixtyCycle
|
||||
return SixtyCycle.from_index(self.get_year().get_heaven_stem().get_index() * 12 + (11 + self.get_month().get_earth_branch().get_index() + self._hour.get_earth_branch().get_index()) % 12 + 2)
|
||||
|
||||
def get_duty(self) -> Duty:
|
||||
"""
|
||||
建除十二值神
|
||||
:return: 建除十二值神
|
||||
"""
|
||||
warnings.warn('get_duty() is deprecated, please use SixtyCycleDay.get_duty() instead.', DeprecationWarning)
|
||||
return Duty(self.get_day().get_earth_branch().get_index() - self.get_month().get_earth_branch().get_index())
|
||||
|
||||
def get_name(self) -> str:
|
||||
return f'{self._three_pillars} {self._hour}'
|
||||
|
||||
def get_solar_times(self, start_year: int, end_year: int) -> List[SolarTime]:
|
||||
"""
|
||||
八字转公历时刻列表
|
||||
:param start_year: 开始年份,支持1-9999年
|
||||
:param end_year: 结束年份,支持1-9999年
|
||||
:return: 公历时刻 SolarTime的列表
|
||||
"""
|
||||
from tyme4py.sixtycycle import HeavenStem
|
||||
from tyme4py.solar import SolarTime, SolarTerm
|
||||
l: List[SolarTime] = []
|
||||
year = self.get_year()
|
||||
month = self.get_month()
|
||||
day = self.get_day()
|
||||
# 月地支距寅月的偏移值
|
||||
m: int = month.get_earth_branch().next(-2).get_index()
|
||||
# 月天干要一致
|
||||
if not HeavenStem((year.get_heaven_stem().get_index() + 1) * 2 + m) == month.get_heaven_stem():
|
||||
return l
|
||||
|
||||
# 1年的立春是辛酉,序号57
|
||||
y: int = year.next(-57).get_index() + 1
|
||||
# 节令偏移值
|
||||
m *= 2
|
||||
# 时辰地支转时刻
|
||||
h: int = self._hour.get_earth_branch().get_index() * 2
|
||||
# 兼容子时多流派
|
||||
hours: List[int] = [0, 23] if h == 0 else [h]
|
||||
base_year: int = start_year - 1
|
||||
if base_year > y:
|
||||
y += 60 * int(ceil((base_year - y) / 60.0))
|
||||
|
||||
while y <= end_year:
|
||||
# 立春为寅月的开始
|
||||
term: SolarTerm = SolarTerm(y, 3)
|
||||
# 节令推移,年干支和月干支就都匹配上了
|
||||
if m > 0:
|
||||
term = term.next(m)
|
||||
|
||||
solar_time: SolarTime = term.get_julian_day().get_solar_time()
|
||||
if solar_time.get_year() >= start_year:
|
||||
# 日干支和节令干支的偏移值
|
||||
solar_day: SolarDay = solar_time.get_solar_day()
|
||||
d: int = day.next(-solar_day.get_lunar_day().get_sixty_cycle().get_index()).get_index()
|
||||
if d > 0:
|
||||
# 从节令推移天数
|
||||
solar_day = solar_day.next(d)
|
||||
for i in range(0, hours.__len__()):
|
||||
mi: int = 0
|
||||
s: int = 0
|
||||
hour: int = hours[i]
|
||||
if d == 0 and hour == solar_time.get_hour():
|
||||
# 如果正好是节令当天,且小时和节令的小时数相等的极端情况,把分钟和秒钟带上
|
||||
mi = solar_time.get_minute()
|
||||
s = solar_time.get_second()
|
||||
|
||||
time: SolarTime = SolarTime(solar_day.get_year(), solar_day.get_month(), solar_day.get_day(), hour, mi, s)
|
||||
if d == 30:
|
||||
time = time.next(-3600)
|
||||
# 验证一下
|
||||
if time.get_lunar_hour().get_eight_char() == self:
|
||||
l.append(time)
|
||||
y += 60
|
||||
return l
|
||||
|
||||
|
||||
class ChildLimitInfo:
|
||||
"""童限信息"""
|
||||
|
||||
def __init__(self, start_time: SolarTime, end_time: SolarTime, year_count: int, month_count: int, day_count: int, hour_count: int, minute_count: int):
|
||||
"""
|
||||
初始化
|
||||
:param start_time: 开始(即出生)的公历时刻
|
||||
:param end_time: 结束(即开始起运)的公历时刻
|
||||
:param year_count: 年数
|
||||
:param month_count: 月数
|
||||
:param day_count: 日数
|
||||
:param hour_count: 小时数
|
||||
:param minute_count: 分钟数
|
||||
"""
|
||||
self._start_time = start_time
|
||||
self._end_time = end_time
|
||||
self._year_count = year_count
|
||||
self._month_count = month_count
|
||||
self._day_count = day_count
|
||||
self._hour_count = hour_count
|
||||
self._minute_count = minute_count
|
||||
|
||||
def get_start_time(self) -> SolarTime:
|
||||
"""
|
||||
:return: 开始(即出生)的公历时刻
|
||||
"""
|
||||
return self._start_time
|
||||
|
||||
def get_end_time(self) -> SolarTime:
|
||||
"""
|
||||
:return: 结束(即开始起运)的公历时刻
|
||||
"""
|
||||
return self._end_time
|
||||
|
||||
def get_year_count(self) -> int:
|
||||
"""
|
||||
:return: 年数
|
||||
"""
|
||||
return self._year_count
|
||||
|
||||
def get_month_count(self) -> int:
|
||||
"""
|
||||
:return: 月数
|
||||
"""
|
||||
return self._month_count
|
||||
|
||||
def get_day_count(self) -> int:
|
||||
"""
|
||||
:return: 日数
|
||||
"""
|
||||
return self._day_count
|
||||
|
||||
def get_hour_count(self) -> int:
|
||||
"""
|
||||
:return: 小时数
|
||||
"""
|
||||
return self._hour_count
|
||||
|
||||
def get_minute_count(self) -> int:
|
||||
"""
|
||||
:return: 分钟数
|
||||
"""
|
||||
return self._minute_count
|
||||
|
||||
|
||||
class ChildLimit:
|
||||
"""童限(从出生到起运的时间段)"""
|
||||
provider: ChildLimitProvider = DefaultChildLimitProvider()
|
||||
"""童限计算接口"""
|
||||
|
||||
def __init__(self, birth_time: SolarTime, gender: Gender):
|
||||
"""
|
||||
通过出生公历时刻初始化
|
||||
:param birth_time: 出生公历时刻
|
||||
:param gender: 性别
|
||||
"""
|
||||
self._gender = gender
|
||||
self._eight_char = birth_time.get_lunar_hour().get_eight_char()
|
||||
# 阳男阴女顺推,阴男阳女逆推
|
||||
yang: bool = YinYang.YANG == self._eight_char.get_year().get_heaven_stem().get_yin_yang()
|
||||
man: bool = Gender.MAN == gender
|
||||
self._forward = (yang and man) or (not yang and not man)
|
||||
term: SolarTerm = birth_time.get_term()
|
||||
if not term.is_jie():
|
||||
term = term.next(-1)
|
||||
if self._forward:
|
||||
term = term.next(2)
|
||||
self._info = ChildLimit.provider.get_info(birth_time, term)
|
||||
|
||||
def get_eight_char(self) -> EightChar:
|
||||
"""
|
||||
:return: 八字
|
||||
"""
|
||||
return self._eight_char
|
||||
|
||||
def get_gender(self) -> Gender:
|
||||
"""
|
||||
:return: 性别
|
||||
"""
|
||||
return self._gender
|
||||
|
||||
def get_year_count(self) -> int:
|
||||
"""
|
||||
:return: 年数
|
||||
"""
|
||||
return self._info.get_year_count()
|
||||
|
||||
def get_month_count(self) -> int:
|
||||
"""
|
||||
:return: 月数
|
||||
"""
|
||||
return self._info.get_month_count()
|
||||
|
||||
def get_day_count(self) -> int:
|
||||
"""
|
||||
:return: 日数
|
||||
"""
|
||||
return self._info.get_day_count()
|
||||
|
||||
def get_hour_count(self) -> int:
|
||||
"""
|
||||
:return: 小时数
|
||||
"""
|
||||
return self._info.get_hour_count()
|
||||
|
||||
def get_minute_count(self) -> int:
|
||||
"""
|
||||
:return: 分钟数
|
||||
"""
|
||||
return self._info.get_minute_count()
|
||||
|
||||
def get_start_time(self) -> SolarTime:
|
||||
"""
|
||||
开始(即出生)的公历时刻
|
||||
:return: 公历时刻
|
||||
"""
|
||||
return self._info.get_start_time()
|
||||
|
||||
def get_end_time(self) -> SolarTime:
|
||||
"""
|
||||
结束(即开始起运)的公历时刻
|
||||
:return: 公历时刻
|
||||
"""
|
||||
return self._info.get_end_time()
|
||||
|
||||
def is_forward(self) -> bool:
|
||||
"""
|
||||
是否顺推
|
||||
:return: true/false
|
||||
"""
|
||||
return self._forward
|
||||
|
||||
def get_start_decade_fortune(self) -> DecadeFortune:
|
||||
"""
|
||||
:return: 起运大运
|
||||
"""
|
||||
return DecadeFortune(self, 0)
|
||||
|
||||
def get_decade_fortune(self) -> DecadeFortune:
|
||||
"""
|
||||
:return: 所属大运
|
||||
"""
|
||||
return DecadeFortune(self, -1)
|
||||
|
||||
def get_start_fortune(self) -> Fortune:
|
||||
"""
|
||||
:return: 小运
|
||||
"""
|
||||
return Fortune(self, 0)
|
||||
|
||||
def get_end_lunar_year(self) -> LunarYear:
|
||||
"""
|
||||
结束农历年
|
||||
:return: 农历年
|
||||
"""
|
||||
warnings.warn('get_end_lunar_year() is deprecated, please use SixtyCycleDay.get_duty() instead.', DeprecationWarning)
|
||||
from tyme4py.lunar import LunarYear
|
||||
return LunarYear.from_year(self.get_start_time().get_lunar_hour().get_year() + self.get_end_time().get_year() - self.get_start_time().get_year())
|
||||
|
||||
def get_start_sixty_cycle_year(self) -> SixtyCycleYear:
|
||||
"""
|
||||
开始(即出生)干支年
|
||||
:return: 干支年
|
||||
"""
|
||||
from tyme4py.sixtycycle import SixtyCycleYear
|
||||
return SixtyCycleYear.from_year(self.get_start_time().get_year())
|
||||
|
||||
def get_end_sixty_cycle_year(self) -> SixtyCycleYear:
|
||||
"""
|
||||
结束(即起运)干支年
|
||||
:return: 干支年
|
||||
"""
|
||||
from tyme4py.sixtycycle import SixtyCycleYear
|
||||
return SixtyCycleYear.from_year(self.get_end_time().get_year())
|
||||
|
||||
@staticmethod
|
||||
def get_start_age() -> int:
|
||||
"""
|
||||
开始年龄
|
||||
:return: 数字
|
||||
"""
|
||||
return 1
|
||||
|
||||
def get_end_age(self) -> int:
|
||||
"""
|
||||
结束年龄
|
||||
:return: 数字
|
||||
"""
|
||||
n: int = self.get_end_sixty_cycle_year().get_year() - self.get_start_sixty_cycle_year().get_year()
|
||||
return max(n, 1)
|
||||
|
||||
|
||||
class Fortune(AbstractTyme):
|
||||
"""小运--在十年大运中,每一年为一小运。童限结束的公历时刻,既是大运的开始,也是小运的开始。"""
|
||||
|
||||
def __init__(self, child_limit: ChildLimit, index: int):
|
||||
"""
|
||||
通过童限初始化
|
||||
:param child_limit: 童限
|
||||
:param index: 序号
|
||||
"""
|
||||
self._child_limit = child_limit
|
||||
self._index = index
|
||||
|
||||
def get_age(self) -> int:
|
||||
"""
|
||||
:return: 年龄
|
||||
"""
|
||||
return self._child_limit.get_end_sixty_cycle_year().get_year() - self._child_limit.get_start_sixty_cycle_year().get_year() + 1 + self._index
|
||||
|
||||
def get_lunar_year(self) -> LunarYear:
|
||||
"""
|
||||
:return: 农历年
|
||||
"""
|
||||
warnings.warn('get_lunar_year() is deprecated, please use get_sixty_cycle_year() instead.', DeprecationWarning)
|
||||
return self._child_limit.get_end_lunar_year().next(self._index)
|
||||
|
||||
def get_sixty_cycle_year(self) -> SixtyCycleYear:
|
||||
"""
|
||||
:return: 干支年
|
||||
"""
|
||||
return self._child_limit.get_end_sixty_cycle_year().next(self._index)
|
||||
|
||||
def get_sixty_cycle(self) -> SixtyCycle:
|
||||
"""
|
||||
:return: 干支
|
||||
"""
|
||||
n: int = self.get_age()
|
||||
return self._child_limit.get_eight_char().get_hour().next(n if self._child_limit.is_forward() else -n)
|
||||
|
||||
def get_name(self) -> str:
|
||||
return self.get_sixty_cycle().get_name()
|
||||
|
||||
def next(self, n: int) -> Fortune:
|
||||
return Fortune(self._child_limit, self._index + n)
|
||||
|
||||
|
||||
class DecadeFortune(AbstractTyme):
|
||||
"""大运(10年1大运)--自起运开始,每十年为一大运。童限结束的公历时刻,即开始起运,是大运的开始。"""
|
||||
|
||||
def __init__(self, child_limit: ChildLimit, index: int):
|
||||
"""
|
||||
通过童限初始化
|
||||
:param child_limit: 童限
|
||||
:param index: 序号
|
||||
"""
|
||||
self._child_limit = child_limit
|
||||
self._index = index
|
||||
|
||||
def get_start_age(self) -> int:
|
||||
"""
|
||||
:return: 开始年龄
|
||||
"""
|
||||
return self._child_limit.get_end_sixty_cycle_year().get_year() - self._child_limit.get_start_sixty_cycle_year().get_year() + 1 + self._index * 10
|
||||
|
||||
def get_end_age(self) -> int:
|
||||
"""
|
||||
:return: 结束年龄
|
||||
"""
|
||||
return self.get_start_age() + 9
|
||||
|
||||
def get_start_lunar_year(self) -> LunarYear:
|
||||
"""
|
||||
开始农历年
|
||||
:return: 农历年
|
||||
"""
|
||||
warnings.warn('get_lunar_year() is deprecated, please use get_sixty_cycle_year() instead.', DeprecationWarning)
|
||||
return self._child_limit.get_end_lunar_year().next(self._index * 10)
|
||||
|
||||
def get_end_lunar_year(self) -> LunarYear:
|
||||
"""
|
||||
结束农历年
|
||||
:return: 农历年
|
||||
"""
|
||||
warnings.warn('get_lunar_year() is deprecated, please use get_sixty_cycle_year() instead.', DeprecationWarning)
|
||||
return self.get_start_lunar_year().next(9)
|
||||
|
||||
def get_start_sixty_cycle_year(self) -> SixtyCycleYear:
|
||||
"""
|
||||
开始干支年
|
||||
:return: 干支年
|
||||
"""
|
||||
return self._child_limit.get_end_sixty_cycle_year().next(self._index * 10)
|
||||
|
||||
def get_end_sixty_cycle_year(self) -> SixtyCycleYear:
|
||||
"""
|
||||
结束干支年
|
||||
:return: 干支年
|
||||
"""
|
||||
return self.get_start_sixty_cycle_year().next(9)
|
||||
|
||||
def get_sixty_cycle(self) -> SixtyCycle:
|
||||
"""
|
||||
:return: 干支
|
||||
"""
|
||||
return self._child_limit.get_eight_char().get_month().next(self._index + 1 if self._child_limit.is_forward() else -self._index - 1)
|
||||
|
||||
def get_name(self) -> str:
|
||||
return self.get_sixty_cycle().get_name()
|
||||
|
||||
def next(self, n: int) -> DecadeFortune:
|
||||
return DecadeFortune(self._child_limit, self._index + n)
|
||||
|
||||
def get_start_fortune(self) -> Fortune:
|
||||
"""
|
||||
本轮大运中开始的小运
|
||||
:return: 小运 Fortune
|
||||
"""
|
||||
return Fortune(self._child_limit, self._index * 10)
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
from __future__ import annotations
|
||||
|
||||
from abc import ABC, abstractmethod
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from tyme4py.eightchar import EightChar
|
||||
from tyme4py.lunar import LunarHour
|
||||
from tyme4py.solar import SolarTime, SolarTerm
|
||||
from tyme4py.eightchar import ChildLimitInfo
|
||||
|
||||
|
||||
class EightCharProvider(ABC):
|
||||
"""八字计算接口"""
|
||||
|
||||
@abstractmethod
|
||||
def get_eight_char(self, hour: LunarHour) -> EightChar:
|
||||
"""
|
||||
八字
|
||||
:param hour: 农历时辰
|
||||
:return: 八字 EightChar
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class ChildLimitProvider(ABC):
|
||||
"""童限计算接口"""
|
||||
|
||||
@abstractmethod
|
||||
def get_info(self, birth_time: SolarTime, term: SolarTerm) -> ChildLimitInfo:
|
||||
"""
|
||||
童限信息
|
||||
:param birth_time:出生公历时刻
|
||||
:param term: 节令
|
||||
:return: 童限信息
|
||||
"""
|
||||
pass
|
||||
+141
@@ -0,0 +1,141 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
from __future__ import annotations
|
||||
|
||||
from abc import abstractmethod
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from tyme4py.eightchar.provider import EightCharProvider, ChildLimitProvider
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from tyme4py.eightchar import EightChar, ChildLimitInfo
|
||||
from tyme4py.lunar import LunarHour
|
||||
from tyme4py.solar import SolarTime, SolarTerm, SolarMonth
|
||||
|
||||
|
||||
class DefaultEightCharProvider(EightCharProvider):
|
||||
"""默认的八字计算(晚子时算第二天)"""
|
||||
|
||||
def get_eight_char(self, hour: LunarHour) -> EightChar:
|
||||
return hour.get_sixty_cycle_hour().get_eight_char()
|
||||
|
||||
|
||||
class LunarSect2EightCharProvider(EightCharProvider):
|
||||
"""Lunar流派2的八字计算(晚子时日柱算当天)"""
|
||||
|
||||
def get_eight_char(self, hour: LunarHour) -> EightChar:
|
||||
from tyme4py.eightchar import EightChar
|
||||
from tyme4py.sixtycycle import SixtyCycleHour
|
||||
h: SixtyCycleHour = hour.get_sixty_cycle_hour()
|
||||
return EightChar(h.get_year(), h.get_month(), hour.get_lunar_day().get_sixty_cycle(), h.get_sixty_cycle())
|
||||
|
||||
|
||||
class AbstractChildLimitProvider(ChildLimitProvider):
|
||||
"""童限计算抽象"""
|
||||
|
||||
@staticmethod
|
||||
def next(birth_time: SolarTime, add_year: int, add_month: int, add_day: int, add_hour: int, add_minute: int, add_second: int) -> ChildLimitInfo:
|
||||
from tyme4py.solar import SolarTime, SolarMonth
|
||||
from tyme4py.eightchar import ChildLimitInfo
|
||||
d: int = birth_time.get_day() + add_day
|
||||
h: int = birth_time.get_hour() + add_hour
|
||||
mi: int = birth_time.get_minute() + add_minute
|
||||
s: int = birth_time.get_second() + add_second
|
||||
mi += s // 60
|
||||
s %= 60
|
||||
h += mi // 60
|
||||
mi %= 60
|
||||
d += h // 24
|
||||
h %= 24
|
||||
sm: SolarMonth = SolarMonth(birth_time.get_year() + add_year, birth_time.get_month()).next(add_month)
|
||||
dc: int = sm.get_day_count()
|
||||
while d > dc:
|
||||
d -= dc
|
||||
sm = sm.next(1)
|
||||
dc = sm.get_day_count()
|
||||
return ChildLimitInfo(birth_time, SolarTime(sm.get_year(), sm.get_month(), d, h, mi, s), add_year, add_month, add_day, add_hour, add_minute)
|
||||
|
||||
@abstractmethod
|
||||
def get_info(self, birth_time: SolarTime, term: SolarTerm) -> ChildLimitInfo:
|
||||
pass
|
||||
|
||||
|
||||
class DefaultChildLimitProvider(AbstractChildLimitProvider):
|
||||
"""默认的八字计算(晚子时算第二天)"""
|
||||
|
||||
def get_info(self, birth_time: SolarTime, term: SolarTerm) -> ChildLimitInfo:
|
||||
# 出生时刻和节令时刻相差的秒数
|
||||
seconds: int = abs(term.get_julian_day().get_solar_time().subtract(birth_time))
|
||||
# 3天 = 1年,3天=60*60*24*3秒=259200秒 = 1年
|
||||
year: int = seconds // 259200
|
||||
seconds %= 259200
|
||||
# 1天 = 4月,1天=60*60*24秒=86400秒 = 4月,85400秒/4=21600秒 = 1月
|
||||
month: int = seconds // 21600
|
||||
seconds %= 21600
|
||||
# 1时 = 5天,1时=60*60秒=3600秒 = 5天,3600秒/5=720秒 = 1天
|
||||
day: int = seconds // 720
|
||||
seconds %= 720
|
||||
# 1分 = 2时,60秒 = 2时,60秒/2=30秒 = 1时
|
||||
hour: int = seconds // 30
|
||||
seconds %= 30
|
||||
# 1秒 = 2分,1秒/2=0.5秒 = 1分
|
||||
minute: int = seconds * 2
|
||||
return AbstractChildLimitProvider.next(birth_time, year, month, day, hour, minute, 0)
|
||||
|
||||
|
||||
class China95ChildLimitProvider(AbstractChildLimitProvider):
|
||||
"""元亨利贞的童限计算"""
|
||||
|
||||
def get_info(self, birth_time: SolarTime, term: SolarTerm) -> ChildLimitInfo:
|
||||
# 出生时刻和节令时刻相差的分钟数
|
||||
minutes: int = int(abs(term.get_julian_day().get_solar_time().subtract(birth_time)) / 60)
|
||||
year: int = minutes // 4320
|
||||
minutes %= 4320
|
||||
month: int = minutes // 360
|
||||
minutes %= 360
|
||||
day: int = minutes // 12
|
||||
return AbstractChildLimitProvider.next(birth_time, year, month, day, 0, 0, 0)
|
||||
|
||||
|
||||
class LunarSect1ChildLimitProvider(AbstractChildLimitProvider):
|
||||
"""Lunar的流派1童限计算(按天数和时辰数计算,3天1年,1天4个月,1时辰10天)"""
|
||||
|
||||
def get_info(self, birth_time: SolarTime, term: SolarTerm) -> ChildLimitInfo:
|
||||
term_time: SolarTime = term.get_julian_day().get_solar_time()
|
||||
end: SolarTime = term_time
|
||||
start: SolarTime = birth_time
|
||||
if birth_time.is_after(term_time):
|
||||
end = birth_time
|
||||
start = term_time
|
||||
|
||||
end_time_zhi_index: int = 11 if end.get_hour() == 23 else end.get_lunar_hour().get_index_in_day()
|
||||
start_time_zhi_index: int = 11 if start.get_hour() == 23 else start.get_lunar_hour().get_index_in_day()
|
||||
# 时辰差
|
||||
hour_diff: int = end_time_zhi_index - start_time_zhi_index
|
||||
# 天数差
|
||||
day_diff: int = end.get_solar_day().subtract(start.get_solar_day())
|
||||
if hour_diff < 0:
|
||||
hour_diff += 12
|
||||
day_diff -= 1
|
||||
|
||||
month_diff: int = int(hour_diff * 10 / 30)
|
||||
month: int = day_diff * 4 + month_diff
|
||||
day: int = hour_diff * 10 - month_diff * 30
|
||||
year: int = int(month / 12)
|
||||
month = month - year * 12
|
||||
return AbstractChildLimitProvider.next(birth_time, year, month, day, 0, 0, 0)
|
||||
|
||||
|
||||
class LunarSect2ChildLimitProvider(AbstractChildLimitProvider):
|
||||
"""Lunar的流派2童限计算(按分钟数计算)"""
|
||||
|
||||
def get_info(self, birth_time: SolarTime, term: SolarTerm) -> ChildLimitInfo:
|
||||
# 出生时刻和节令时刻相差的分钟数
|
||||
minutes: int = int(abs(term.get_julian_day().get_solar_time().subtract(birth_time)) / 60)
|
||||
year: int = int(minutes / 4320)
|
||||
minutes %= 4320
|
||||
month: int = int(minutes / 360)
|
||||
minutes %= 360
|
||||
day: int = int(minutes / 12)
|
||||
minutes %= 12
|
||||
hour: int = minutes * 2
|
||||
return AbstractChildLimitProvider.next(birth_time, year, month, day, hour, 0, 0)
|
||||
Vendored
+52
@@ -0,0 +1,52 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
from enum import Enum
|
||||
|
||||
|
||||
class YinYang(Enum):
|
||||
"""阴阳:YIN=0=阴,YANG=1=阳"""
|
||||
YIN = 0
|
||||
"""阴"""
|
||||
YANG = 1
|
||||
"""阳"""
|
||||
|
||||
|
||||
class Side(Enum):
|
||||
"""内外:IN=0=内,OUT=1=外"""
|
||||
IN = 0
|
||||
"""内"""
|
||||
OUT = 1
|
||||
"""外"""
|
||||
|
||||
|
||||
class Gender(Enum):
|
||||
"""性别:WOMAN=0=女,MAN=1=男"""
|
||||
WOMAN = 0
|
||||
"""女"""
|
||||
MAN = 1
|
||||
"""男"""
|
||||
|
||||
|
||||
class HideHeavenStemType(Enum):
|
||||
"""藏干类型:RESIDUAL=0=余气,MIDDLE=1=中气,MAIN=2=本气"""
|
||||
RESIDUAL = 0
|
||||
"""余气"""
|
||||
MIDDLE = 1
|
||||
"""中气"""
|
||||
MAIN = 2
|
||||
"""本气"""
|
||||
|
||||
|
||||
class EventType(Enum):
|
||||
"""事件类型"""
|
||||
SOLAR_DAY = 0
|
||||
"""公历日期"""
|
||||
SOLAR_WEEK = 1
|
||||
"""几月第几个星期几"""
|
||||
LUNAR_DAY = 2
|
||||
"""农历日期"""
|
||||
TERM_DAY = 3
|
||||
"""节气日期"""
|
||||
TERM_HS = 4
|
||||
"""节气天干"""
|
||||
TERM_EB = 5
|
||||
"""节气地支"""
|
||||
Vendored
+361
@@ -0,0 +1,361 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
from typing import Union, List, TYPE_CHECKING
|
||||
|
||||
from tyme4py import AbstractCulture
|
||||
from tyme4py.enums import EventType
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from tyme4py.solar import SolarMonth, SolarDay, SolarTerm
|
||||
from tyme4py.lunar import LunarMonth, LunarDay
|
||||
|
||||
|
||||
class Event(AbstractCulture):
|
||||
"""事件"""
|
||||
|
||||
def __init__(self, name: str, data: str):
|
||||
Event.validate(data)
|
||||
self._name = name
|
||||
self._data = data
|
||||
|
||||
@staticmethod
|
||||
def validate(data: str) -> None:
|
||||
if len(data) != 9:
|
||||
raise ValueError(f'illegal event data: {data}')
|
||||
|
||||
@staticmethod
|
||||
def builder() -> EventBuilder:
|
||||
"""构造器"""
|
||||
return EventBuilder()
|
||||
|
||||
@classmethod
|
||||
def from_name(cls, name: str) -> Union[Event, None]:
|
||||
pattern: re.Pattern[str] = re.compile(f'{EventManager.REGEX}{name}')
|
||||
matcher: Union[re.Match[str], None] = pattern.search(EventManager.DATA)
|
||||
return cls(name, matcher.group(1)) if matcher else None
|
||||
|
||||
def _get_char_index(self, index: int) -> int:
|
||||
return EventManager.CHARS.index(self._data[index])
|
||||
|
||||
def get_value(self, index: int) -> int:
|
||||
return self._get_char_index(index) - 31
|
||||
|
||||
def get_month(self, year: int) -> List[int]:
|
||||
y: int = year
|
||||
m: int = self.get_value(2)
|
||||
if m > 12:
|
||||
m = 1
|
||||
y += 1
|
||||
return [y, m]
|
||||
|
||||
def get_type(self) -> EventType:
|
||||
"""事件类型"""
|
||||
n: int = self._get_char_index(1)
|
||||
if n == 1:
|
||||
return EventType.SOLAR_WEEK
|
||||
if n == 2:
|
||||
return EventType.LUNAR_DAY
|
||||
if n == 3:
|
||||
return EventType.TERM_DAY
|
||||
if n == 4:
|
||||
return EventType.TERM_HS
|
||||
if n == 5:
|
||||
return EventType.TERM_EB
|
||||
return EventType.SOLAR_DAY
|
||||
|
||||
def get_name(self) -> str:
|
||||
"""名称"""
|
||||
return self._name
|
||||
|
||||
def get_data(self) -> str:
|
||||
"""数据"""
|
||||
return self._data
|
||||
|
||||
def get_start_year(self) -> int:
|
||||
"""起始年"""
|
||||
n: int = 0
|
||||
size: int = len(EventManager.CHARS)
|
||||
for i in range(0, 3):
|
||||
n = n * size + self._get_char_index(6 + i)
|
||||
return n
|
||||
|
||||
def get_solar_day(self, year: int) -> Union[SolarDay, None]:
|
||||
if year < self.get_start_year():
|
||||
return None
|
||||
t: EventType = self.get_type()
|
||||
d: Union[SolarDay, None] = None
|
||||
if t == EventType.SOLAR_DAY:
|
||||
d = self._get_solar_day_by_solar_day(year)
|
||||
elif t == EventType.SOLAR_WEEK:
|
||||
d = self._get_solar_day_by_week(year)
|
||||
elif t == EventType.LUNAR_DAY:
|
||||
d = self._get_solar_day_by_lunar_day(year)
|
||||
elif t == EventType.TERM_DAY:
|
||||
d = self._get_solar_day_by_term(year)
|
||||
elif t == EventType.TERM_HS:
|
||||
d = self._get_solar_day_by_term_heaven_stem(year)
|
||||
elif t == EventType.TERM_EB:
|
||||
d = self._get_solar_day_by_term_earth_branch(year)
|
||||
if d is None:
|
||||
return None
|
||||
offset: int = self.get_value(5)
|
||||
return d if 0 == offset else d.next(offset)
|
||||
|
||||
def _get_solar_day_by_solar_day(self, year: int) -> Union[SolarDay, None]:
|
||||
from tyme4py.solar import SolarMonth, SolarDay
|
||||
month: List[int] = self.get_month(year)
|
||||
y: int = month[0]
|
||||
m: int = month[1]
|
||||
d: int = self.get_value(3)
|
||||
delay: int = self.get_value(4)
|
||||
last_day: int = SolarMonth.from_ym(y, m).get_day_count()
|
||||
if d > last_day:
|
||||
if 0 == delay:
|
||||
return None
|
||||
elif delay < 0:
|
||||
return SolarDay.from_ymd(y, m, d + delay)
|
||||
return SolarDay.from_ymd(y, m, last_day).next(delay)
|
||||
return SolarDay.from_ymd(y, m, d)
|
||||
|
||||
def _get_solar_day_by_lunar_day(self, year: int) -> Union[SolarDay, None]:
|
||||
from tyme4py.lunar import LunarMonth, LunarDay
|
||||
month: List[int] = self.get_month(year)
|
||||
y: int = month[0]
|
||||
m: int = month[1]
|
||||
d: int = self.get_value(3)
|
||||
delay: int = self.get_value(4)
|
||||
last_day: int = LunarMonth.from_ym(y, m).get_day_count()
|
||||
if d > last_day:
|
||||
if 0 == delay:
|
||||
return None
|
||||
elif delay < 0:
|
||||
return LunarDay.from_ymd(y, m, d + delay).get_solar_day()
|
||||
return LunarDay.from_ymd(y, m, last_day).get_solar_day().next(delay)
|
||||
return LunarDay.from_ymd(y, m, d).get_solar_day()
|
||||
|
||||
def _get_solar_day_by_week(self, year: int) -> Union[SolarDay, None]:
|
||||
from tyme4py.solar import SolarMonth, SolarDay
|
||||
# 第几个星期
|
||||
n: int = self.get_value(3)
|
||||
if n == 0:
|
||||
return None
|
||||
m: SolarMonth = SolarMonth.from_ym(year, self.get_value(2))
|
||||
# 星期几
|
||||
w: int = self.get_value(4)
|
||||
if n > 0:
|
||||
# 当月第1天
|
||||
d: SolarDay = m.get_first_day()
|
||||
# 往后找第几个星期几
|
||||
return d.next(d.get_week().steps_to(w) + 7 * n - 7)
|
||||
|
||||
# 当月最后一天
|
||||
d: SolarDay = SolarDay.from_ymd(year, m.get_month(), m.get_day_count())
|
||||
# 往前找第几个星期几
|
||||
return d.next(d.get_week().steps_back_to(w) + 7 * n + 7)
|
||||
|
||||
def _get_solar_day_by_term(self, year: int) -> Union[SolarDay, None]:
|
||||
from tyme4py.solar import SolarTerm, SolarDay
|
||||
d: SolarDay = SolarTerm.from_index(year, self.get_value(2)).get_solar_day()
|
||||
offset: int = self.get_value(4)
|
||||
return d if 0 == offset else d.next(offset)
|
||||
|
||||
def _get_solar_day_by_term_heaven_stem(self, year: int) -> Union[SolarDay, None]:
|
||||
from tyme4py.solar import SolarDay
|
||||
d: SolarDay = self._get_solar_day_by_term(year)
|
||||
return d.next(d.get_lunar_day().get_sixty_cycle().get_heaven_stem().steps_to(self.get_value(3)))
|
||||
|
||||
def _get_solar_day_by_term_earth_branch(self, year: int) -> Union[SolarDay, None]:
|
||||
from tyme4py.solar import SolarDay
|
||||
d: SolarDay = self._get_solar_day_by_term(year)
|
||||
return d.next(d.get_lunar_day().get_sixty_cycle().get_earth_branch().steps_to(self.get_value(3)))
|
||||
|
||||
@classmethod
|
||||
def from_solar_day(cls, d: SolarDay) -> List[Event]:
|
||||
"""
|
||||
指定公历日的事件列表
|
||||
:param d: 公历日
|
||||
"""
|
||||
l: List[Event] = []
|
||||
for e in cls.all():
|
||||
if d == e.get_solar_day(d.get_year()):
|
||||
l.append(e)
|
||||
return l
|
||||
|
||||
@classmethod
|
||||
def all(cls) -> List[Event]:
|
||||
l: List[Event] = []
|
||||
pattern: re.Pattern[str] = re.compile(f'{EventManager.REGEX}(.[^@]+)')
|
||||
matcher: Union[re.Match[str], None] = pattern.search(EventManager.DATA)
|
||||
while matcher:
|
||||
l.append(cls(matcher.group(2), matcher.group(1)))
|
||||
matcher = pattern.search(EventManager.DATA, matcher.end())
|
||||
return l
|
||||
|
||||
|
||||
class EventBuilder:
|
||||
"""事件构造器"""
|
||||
|
||||
def __init__(self):
|
||||
self._name = ''
|
||||
self._data = ['@', '_', '_', '_', '_', '_', '0', '0', '0']
|
||||
|
||||
def name(self, n: str) -> EventBuilder:
|
||||
self._name = n
|
||||
return self
|
||||
|
||||
@staticmethod
|
||||
def _get_char(index: int) -> str:
|
||||
return EventManager.CHARS[index]
|
||||
|
||||
def _set_value(self, index: int, n: int) -> EventBuilder:
|
||||
self._data[index] = self._get_char(31 + n)
|
||||
return self
|
||||
|
||||
@staticmethod
|
||||
def encode_type(t: EventType) -> str:
|
||||
n: int = 0
|
||||
if t == EventType.SOLAR_WEEK:
|
||||
n = 1
|
||||
elif t == EventType.LUNAR_DAY:
|
||||
n = 2
|
||||
elif t == EventType.TERM_DAY:
|
||||
n = 3
|
||||
elif t == EventType.TERM_HS:
|
||||
n = 4
|
||||
elif t == EventType.TERM_EB:
|
||||
n = 5
|
||||
return EventBuilder._get_char(n)
|
||||
|
||||
def _content(self, t: EventType, a: int, b: int, c: int) -> EventBuilder:
|
||||
self._data[1] = self.encode_type(t)
|
||||
return self._set_value(2, a)._set_value(3, b)._set_value(4, c)
|
||||
|
||||
def solar_day(self, solar_month: int, solar_day: int, delay_days: int) -> EventBuilder:
|
||||
"""
|
||||
公历日
|
||||
:param solar_month: 公历月(1至12)
|
||||
:param solar_day: 公历日(1至31)
|
||||
:param delay_days: 顺延天数,例如生日在2月29,非闰年没有2月29,是+1天,还是-1天(最远支持-31至31天)
|
||||
:return: 事件构造器
|
||||
"""
|
||||
return self._content(EventType.SOLAR_DAY, solar_month, solar_day, delay_days)
|
||||
|
||||
def lunar_day(self, lunar_month: int, lunar_day: int, delay_days: int) -> EventBuilder:
|
||||
"""
|
||||
农历日
|
||||
:param lunar_month: 农历月(-12至-1,1至12,闰月为负)
|
||||
:param lunar_day: 农历日(1至30)
|
||||
:param delay_days: 顺延天数,例如生日在某月的三十,但下一年当月可能只有29天,是+1天,还是-1天(最远支持-31至31天)
|
||||
:return: 事件构造器
|
||||
"""
|
||||
return self._content(EventType.LUNAR_DAY, lunar_month, lunar_day, delay_days)
|
||||
|
||||
def solar_week(self, solar_month: int, week_index: int, week: int) -> EventBuilder:
|
||||
"""
|
||||
公历第几个星期几
|
||||
:param solar_month: 公历月(1至12)
|
||||
:param week_index: 第几个星期(1为第1个星期,-1为倒数第1个星期)
|
||||
:param week: 星期几(0至6,0代表星期天,1代表星期一)
|
||||
:return: 事件构造器
|
||||
"""
|
||||
return self._content(EventType.SOLAR_WEEK, solar_month, week_index, week)
|
||||
|
||||
def term_day(self, term_index: int, delay_days: int) -> EventBuilder:
|
||||
"""
|
||||
节气
|
||||
:param term_index: 节气索引(0至23)
|
||||
:param delay_days: 顺延天数(最远支持-31至31天)
|
||||
:return: 事件构造器
|
||||
"""
|
||||
return self._content(EventType.TERM_DAY, term_index, 0, delay_days)
|
||||
|
||||
def term_heaven_stem(self, term_index: int, heaven_stem_index: int, delay_days: int) -> EventBuilder:
|
||||
"""
|
||||
节气天干
|
||||
:param term_index: 节气索引(0至23)
|
||||
:param heaven_stem_index: 天干索引(0至9)
|
||||
:param delay_days: 顺延天数(最远支持-31至31天)
|
||||
:return: 事件构造器
|
||||
"""
|
||||
return self._content(EventType.TERM_HS, term_index, heaven_stem_index, delay_days)
|
||||
|
||||
def term_earth_branch(self, term_index: int, earth_branch_index: int, delay_days: int) -> EventBuilder:
|
||||
"""
|
||||
节气地支
|
||||
:param term_index: 节气索引(0至23)
|
||||
:param earth_branch_index: 地支索引(0至11)
|
||||
:param delay_days: 顺延天数(最远支持-31至31天)
|
||||
:return: 事件构造器
|
||||
"""
|
||||
return self._content(EventType.TERM_EB, term_index, earth_branch_index, delay_days)
|
||||
|
||||
def start_year(self, year: int) -> EventBuilder:
|
||||
"""
|
||||
起始年
|
||||
:param year: 年
|
||||
:return: 事件构造器
|
||||
"""
|
||||
size: int = len(EventManager.CHARS)
|
||||
n: int = year
|
||||
for i in range(3):
|
||||
self._data[8 - i] = self._get_char(n % size)
|
||||
n //= size
|
||||
return self
|
||||
|
||||
def offset(self, days: int) -> EventBuilder:
|
||||
"""
|
||||
偏移天数
|
||||
:param days: 天数(最远支持-31至31天)
|
||||
:return: 事件构造器
|
||||
"""
|
||||
return self._set_value(5, days)
|
||||
|
||||
def build(self) -> Event:
|
||||
"""
|
||||
生成事件
|
||||
:return: 事件
|
||||
"""
|
||||
return Event(self._name, ''.join(self._data))
|
||||
|
||||
|
||||
class EventManager:
|
||||
"""事件管理器"""
|
||||
|
||||
CHARS: str = '0123456789ABCDEFGHIJKLMNOPQRSTU_VWXYZabcdefghijklmnopqrstuvwxyz'
|
||||
"""有效字符"""
|
||||
DATA: str = ''
|
||||
"""全量事件数据"""
|
||||
REGEX: str = '(@[0-9A-Za-z_]{8})'
|
||||
"""数据匹配的正则表达式"""
|
||||
|
||||
@classmethod
|
||||
def remove(cls, name: str) -> None:
|
||||
"""
|
||||
删除事件
|
||||
:param name: 名称
|
||||
"""
|
||||
cls.DATA = re.sub(rf'{cls.REGEX}{name}', '', cls.DATA)
|
||||
|
||||
@classmethod
|
||||
def _save_or_update(cls, name: str, data: str) -> None:
|
||||
"""
|
||||
删除事件
|
||||
:param name: 名称
|
||||
"""
|
||||
pattern: re.Pattern[str] = re.compile(f'{cls.REGEX}{name}')
|
||||
matcher: Union[re.Match[str], None] = pattern.search(cls.DATA)
|
||||
if matcher:
|
||||
cls.DATA = re.sub(rf'{cls.REGEX}{name}', data, EventManager.DATA)
|
||||
else:
|
||||
cls.DATA += data
|
||||
|
||||
@classmethod
|
||||
def update(cls, name: str, e: Event) -> None:
|
||||
cls._save_or_update(name, e.get_data() + name if e.get_name() is None or len(e.get_name()) < 1 else e.get_name())
|
||||
|
||||
@classmethod
|
||||
def update_data(cls, name: str, data: str) -> None:
|
||||
Event.validate(data)
|
||||
cls._save_or_update(name, data)
|
||||
Vendored
+205
@@ -0,0 +1,205 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
from __future__ import annotations
|
||||
|
||||
from abc import abstractmethod
|
||||
from typing import TYPE_CHECKING, List, Union
|
||||
|
||||
from tyme4py import AbstractTyme, Tyme
|
||||
from tyme4py.enums import EventType
|
||||
from tyme4py.event import Event
|
||||
from tyme4py.unit import DayUnit
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from tyme4py.lunar import LunarDay
|
||||
from tyme4py.solar import SolarTerm, SolarDay
|
||||
|
||||
|
||||
class AbstractFestival(AbstractTyme):
|
||||
@abstractmethod
|
||||
def next(self, n: int) -> Union[Tyme, None]:
|
||||
pass
|
||||
|
||||
def __init__(self, index: int, event: Event, day: DayUnit):
|
||||
self._index = index
|
||||
self._event = event
|
||||
self._day = day
|
||||
|
||||
def get_name(self) -> str:
|
||||
return self._event.get_name()
|
||||
|
||||
def get_index(self) -> int:
|
||||
"""
|
||||
:return: 索引
|
||||
"""
|
||||
return self._index
|
||||
|
||||
def get_day(self) -> DayUnit:
|
||||
"""
|
||||
:return: 日
|
||||
"""
|
||||
return self._day
|
||||
|
||||
def __str__(self) -> str:
|
||||
return f'{self._day} {self.get_name()}'
|
||||
|
||||
class LunarFestival(AbstractFestival):
|
||||
"""
|
||||
农历传统节日--依据国家标准《农历的编算和颁行》GB/T 33661-2017
|
||||
农历传统节日有:春节、元宵节、龙头节、上巳节、清明节、端午节、七夕节、中元节、中秋节、重阳节、冬至节、腊八节、除夕。
|
||||
"""
|
||||
NAMES: List[str] = ['春节', '元宵节', '龙头节', '上巳节', '清明节', '端午节', '七夕节', '中元节', '中秋节', '重阳节', '冬至节', '腊八节', '除夕']
|
||||
"""名称"""
|
||||
DATA: str = '2VV__0002Vj__0002WW__0002XX__0003b___0002ZZ__0002bb__0002bj__0002cj__0002dd__0003s___0002gc__0002hV_U000'
|
||||
|
||||
def __init__(self, index: int, event: Event, day: LunarDay):
|
||||
"""
|
||||
实例化
|
||||
:param index: 索引
|
||||
:param event: 事件
|
||||
:param day: 农历日
|
||||
"""
|
||||
super().__init__(index, event, day)
|
||||
|
||||
@classmethod
|
||||
def from_index(cls, year: int, index: int) -> Union[LunarFestival, None]:
|
||||
"""
|
||||
指定索引得到
|
||||
:param year: 年
|
||||
:param index: 索引
|
||||
:return:
|
||||
"""
|
||||
if index < 0 or index >= cls.NAMES.__len__():
|
||||
return None
|
||||
from tyme4py.lunar import LunarDay
|
||||
from tyme4py.solar import SolarTerm
|
||||
start: int = index * 8
|
||||
e: Event = Event(LunarFestival.NAMES[index], '@' + LunarFestival.DATA[start: start + 8])
|
||||
t: EventType = e.get_type()
|
||||
if t == EventType.LUNAR_DAY:
|
||||
m: List[int] = e.get_month(year)
|
||||
d: LunarDay = LunarDay.from_ymd(m[0], m[1], e.get_value(3))
|
||||
offset: int = e.get_value(5)
|
||||
return LunarFestival(index, e, d if offset == 0 else d.next(offset))
|
||||
elif t == EventType.TERM_DAY:
|
||||
return LunarFestival(index, e, SolarTerm.from_index(year, e.get_value(2)).get_solar_day().get_lunar_day())
|
||||
return None
|
||||
|
||||
@classmethod
|
||||
def from_ymd(cls, year: int, month: int, day: int) -> Union[LunarFestival, None]:
|
||||
"""
|
||||
指定农历年、月、日得到
|
||||
:param year: 农历年
|
||||
:param month: 农历月
|
||||
:param day: 农历日
|
||||
:return:
|
||||
"""
|
||||
from tyme4py.lunar import LunarDay
|
||||
from tyme4py.solar import SolarTermDay
|
||||
d: LunarDay = LunarDay.from_ymd(year, month, day)
|
||||
for i in range(0, LunarFestival.NAMES.__len__()):
|
||||
start: int = i * 8
|
||||
e: Event = Event(LunarFestival.NAMES[i], '@' + LunarFestival.DATA[start: start + 8])
|
||||
t: EventType = e.get_type()
|
||||
if t == EventType.LUNAR_DAY:
|
||||
offset: int = e.get_value(5)
|
||||
if offset == 0:
|
||||
if d.get_month() == e.get_value(2) and d.get_day() == e.get_value(3):
|
||||
return LunarFestival(i, e, d)
|
||||
else:
|
||||
m: List[int] = e.get_month(d.get_year())
|
||||
n: LunarDay = d.next(-offset)
|
||||
if n.get_year() == m[0] and n.get_month() == m[1] and n.get_day() == e.get_value(3):
|
||||
return LunarFestival(i, e, d)
|
||||
elif t == EventType.TERM_DAY:
|
||||
term: SolarTermDay = d.get_solar_day().get_term_day()
|
||||
if term.get_day_index() == 0 and term.get_solar_term().get_index() == e.get_value(2) % 24:
|
||||
return LunarFestival(i, e, d)
|
||||
return None
|
||||
|
||||
def get_day(self) -> LunarDay:
|
||||
"""
|
||||
:return: 农历日
|
||||
"""
|
||||
return super().get_day()
|
||||
|
||||
def get_solar_term(self) -> Union[SolarTerm, None]:
|
||||
"""
|
||||
节气,非节气返回None
|
||||
:return: 节气
|
||||
"""
|
||||
from tyme4py.solar import SolarTermDay
|
||||
t: SolarTermDay = self.get_day().get_solar_day().get_term_day()
|
||||
return t.get_solar_term() if t.get_day_index() == 0 else None
|
||||
|
||||
def next(self, n: int) -> LunarFestival:
|
||||
size: int = LunarFestival.NAMES.__len__()
|
||||
i: int = self._index + n
|
||||
return LunarFestival.from_index(int((self._day.get_year() * size + i) / size), self.index_of(i, size))
|
||||
|
||||
|
||||
class SolarFestival(AbstractFestival):
|
||||
"""公历现代节日"""
|
||||
NAMES: List[str] = ['元旦', '妇女节', '植树节', '劳动节', '青年节', '儿童节', '建党节', '建军节', '教师节', '国庆节']
|
||||
DATA: str = '0VV__0Ux0Xc__0Ux0Xg__0_Q0ZV__0Ux0ZY__0Ux0aV__0Ux0bV__0Uo0cV__0Ug0de__0_V0eV__0Ux'
|
||||
|
||||
def __init__(self, index: int, event: Event, day: SolarDay):
|
||||
"""
|
||||
实例化
|
||||
:param index: 索引
|
||||
:param event: 事件
|
||||
:param day: 公历日
|
||||
"""
|
||||
super().__init__(index, event, day)
|
||||
|
||||
@classmethod
|
||||
def from_index(cls, year: int, index: int) -> Union[SolarFestival, None]:
|
||||
"""
|
||||
指定索引得到
|
||||
:param year: 年份
|
||||
:param index: 索引
|
||||
:return:
|
||||
"""
|
||||
if index < 0 or index >= cls.NAMES.__len__():
|
||||
return None
|
||||
start: int = index * 8
|
||||
e: Event = Event(SolarFestival.NAMES[index], '@' + SolarFestival.DATA[start: start + 8])
|
||||
if year < e.get_start_year():
|
||||
return None
|
||||
from tyme4py.solar import SolarDay
|
||||
return SolarFestival(index, e, SolarDay.from_ymd(year, e.get_value(2), e.get_value(3)))
|
||||
|
||||
@classmethod
|
||||
def from_ymd(cls, year: int, month: int, day: int) -> Union[SolarFestival, None]:
|
||||
"""
|
||||
指定年、月、日得到
|
||||
:param year: 年
|
||||
:param month: 月
|
||||
:param day: 日
|
||||
:return:
|
||||
"""
|
||||
from tyme4py.solar import SolarDay
|
||||
d: SolarDay = SolarDay.from_ymd(year, month, day)
|
||||
for i in range(0, SolarFestival.NAMES.__len__()):
|
||||
start: int = i * 8
|
||||
e: Event = Event(SolarFestival.NAMES[i], '@' + SolarFestival.DATA[start: start + 8])
|
||||
if d.get_year() >= e.get_start_year() and d.get_month() == e.get_value(2) and d.get_day() == e.get_value(3):
|
||||
return SolarFestival(i, e, d)
|
||||
return None
|
||||
|
||||
def get_day(self) -> SolarDay:
|
||||
"""
|
||||
:return: 公历日
|
||||
"""
|
||||
return super().get_day()
|
||||
|
||||
def get_start_year(self) -> int:
|
||||
"""
|
||||
起始年
|
||||
:return: 年
|
||||
"""
|
||||
return self._event.get_start_year()
|
||||
|
||||
def next(self, n: int) -> Union[SolarFestival, None]:
|
||||
size: int = SolarFestival.NAMES.__len__()
|
||||
i: int = self._index + n
|
||||
return SolarFestival.from_index(int((self._day.get_year() * size + i) / size), self.index_of(i, size))
|
||||
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)))
|
||||
Vendored
+110
File diff suppressed because one or more lines are too long
Vendored
+111
@@ -0,0 +1,111 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
from __future__ import annotations
|
||||
from tyme4py import AbstractTyme
|
||||
from tyme4py.culture import Week
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from tyme4py.solar import SolarDay, SolarTime
|
||||
|
||||
|
||||
class JulianDay(AbstractTyme):
|
||||
"""儒略日"""
|
||||
J2000: float = 2451545
|
||||
"""2000年儒略日数(2000-1-1 12:00:00 UTC)"""
|
||||
|
||||
def __init__(self, day: float):
|
||||
"""
|
||||
:param day: 为小数
|
||||
"""
|
||||
self._day = day
|
||||
|
||||
@classmethod
|
||||
def from_julian_day(cls, day: float) -> JulianDay:
|
||||
return cls(day)
|
||||
|
||||
@classmethod
|
||||
def from_ymd_hms(cls, year: int, month: int, day: int, hour: int, minute: int, second: int) -> JulianDay:
|
||||
"""
|
||||
通过公历年月日时分秒进行初始化
|
||||
:param year: 年
|
||||
:param month: 月
|
||||
:param day: 日
|
||||
:param hour: 时
|
||||
:param minute: 分
|
||||
:param second: 秒
|
||||
:return:
|
||||
"""
|
||||
d: float = day + ((second / 60 + minute) / 60 + hour) / 24
|
||||
n: int = 0
|
||||
g: bool = year * 372 + month * 31 + int(d) >= 588829
|
||||
if month <= 2:
|
||||
month += 12
|
||||
year -= 1
|
||||
if g:
|
||||
n = int(year * 0.01)
|
||||
n = 2 - n + int(n * 0.25)
|
||||
return cls(int(365.25 * (year + 4716)) + int(30.6001 * (month + 1)) + d + n - 1524.5)
|
||||
|
||||
def get_day(self) -> float:
|
||||
"""
|
||||
:return: 儒略日
|
||||
"""
|
||||
return self._day
|
||||
|
||||
def get_name(self) -> str:
|
||||
return f'{self._day}'
|
||||
|
||||
def next(self, n: float) -> JulianDay:
|
||||
return JulianDay(self._day + n)
|
||||
|
||||
def get_solar_day(self) -> SolarDay:
|
||||
"""
|
||||
:return: 公历日
|
||||
"""
|
||||
return self.get_solar_time().get_solar_day()
|
||||
|
||||
def get_solar_time(self) -> SolarTime:
|
||||
"""
|
||||
:return: 公历时刻
|
||||
"""
|
||||
d: int = int(self._day + 0.5)
|
||||
f: float = self._day + 0.5 - d
|
||||
if d >= 2299161:
|
||||
c: int = int((d - 1867216.25) / 36524.25)
|
||||
d += 1 + c - int(c * 0.25)
|
||||
d += 1524
|
||||
y: int = int((d - 122.1) / 365.25)
|
||||
d -= int(365.25 * y)
|
||||
m: int = int(d / 30.601)
|
||||
d -= int(30.601 * m)
|
||||
if m > 13:
|
||||
m -= 12
|
||||
else:
|
||||
y -= 1
|
||||
m -= 1
|
||||
y -= 4715
|
||||
f *= 24
|
||||
hour: int = int(f)
|
||||
f -= hour
|
||||
f *= 60
|
||||
minute: int = int(f)
|
||||
f -= minute
|
||||
f *= 60
|
||||
second: int = round(f)
|
||||
from tyme4py.solar import SolarTime
|
||||
return SolarTime(y, m, d, hour, minute, second) if second < 60 else SolarTime(y, m, d, hour, minute, second - 60).next(60)
|
||||
|
||||
def get_week(self) -> Week:
|
||||
"""
|
||||
通过儒略日计算的星期是最准的,基姆拉尔森和蔡勒公式计算星期的准确性,在儒略日面前都是弟弟,不服来辩
|
||||
:return: 星期
|
||||
"""
|
||||
return Week(int(self._day + 0.5) + 7000001)
|
||||
|
||||
def subtract(self, target: JulianDay) -> float:
|
||||
"""
|
||||
儒略日相减
|
||||
:param target: 儒略日
|
||||
:return: 差
|
||||
"""
|
||||
return self._day - target.get_day()
|
||||
Vendored
+941
@@ -0,0 +1,941 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
from __future__ import annotations
|
||||
|
||||
import warnings
|
||||
from math import floor, ceil
|
||||
from typing import TYPE_CHECKING, List, Union
|
||||
|
||||
from tyme4py import LoopTyme
|
||||
from tyme4py.culture import Twenty, Direction, KitchenGodSteed, Week, Duty, Phase, God, Taboo, PhaseDay
|
||||
from tyme4py.culture.star.twentyeight import TwentyEightStar
|
||||
from tyme4py.culture.fetus import FetusMonth, FetusDay
|
||||
from tyme4py.culture.ren import MinorRen
|
||||
from tyme4py.culture.star.nine import NineStar
|
||||
from tyme4py.culture.star.six import SixStar
|
||||
from tyme4py.culture.star.twelve import TwelveStar
|
||||
from tyme4py.eightchar import EightChar
|
||||
from tyme4py.eightchar.provider import EightCharProvider
|
||||
from tyme4py.eightchar.provider.impl import DefaultEightCharProvider
|
||||
from tyme4py.festival import LunarFestival
|
||||
from tyme4py.jd import JulianDay
|
||||
from tyme4py.unit import YearUnit, MonthUnit, WeekUnit, DayUnit, SecondUnit
|
||||
from tyme4py.util import ShouXingUtil
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from tyme4py.solar import SolarDay, SolarTime, SolarTerm
|
||||
from tyme4py.sixtycycle import SixtyCycle, SixtyCycleDay, SixtyCycleHour, ThreePillars
|
||||
|
||||
|
||||
class LunarYear(YearUnit):
|
||||
"""
|
||||
农历年
|
||||
依据国家标准《农历的编算和颁行》GB/T 33661-2017,农历年以正月初一开始,至除夕结束。
|
||||
"""
|
||||
_IS_INIT: bool = False
|
||||
_LEAP: List[List[int]] = []
|
||||
|
||||
@staticmethod
|
||||
def _init():
|
||||
if LunarYear._IS_INIT:
|
||||
return
|
||||
chars: str = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_@'
|
||||
months: List[str] = [
|
||||
'080b0r0j0j0j0C0j0j0C0j0j0j0C0j0C0j0C0F0j0V0V0V0u0j0j0C0j0j0j0j0V0C0j1v0u0C0V1v0C0b080u110u0C0j0C1v9K1v2z0j1vmZbl1veN3s1v0V0C2S1v0V0C2S2o0C0j1Z1c2S1v0j1c0j2z1v0j1c0j392H0b2_2S0C0V0j1c0j2z0C0C0j0j1c0j0N250j0C0j0b081n080b0C0C0C1c0j0N',
|
||||
'0r1v1c1v0V0V0F0V0j0C0j0C0j0V0j0u1O0j0C0V0j0j0j0V0b080u0r0u080b0j0j0C0V0C0V0j0b080V0u080b0j0j0u0j1v0u080b1c0j080b0j0V0j0j0V0C0N1v0j1c0j0j1v2g1v420j1c0j2z1v0j1v5Q9z1v4l0j1vfn1v420j9z4l1v1v2S1c0j1v2S3s1v0V0C2S1v1v2S1c0j1v2S2_0b0j2_2z0j1c0j',
|
||||
'0z0j0j0j0C0j0j0C0j0j0j0C0j0C0j0j0j0j0m0j0C0j0j0C0j0j0j0j0b0V0j0j0C0j0j0j0j0V0j0j0j0V0b0V0V0C0V0C0j0j0b080u110u0V0C0j0N0j0b080b080b0j0r0b0r0b0j0j0j0j0C0j0b0r0C0j0b0j0C0C0j0j0j0j0j0j0j0j0j0b110j0b0j0j0j0C0j0C0j0j0j0j0b080b080b0V080b080b0j0j0j0j0j0j0V0j0j0u1v0j0j0j0C0j0j0j0V0C0N1c0j0C0C0j0j0j1n080b0j0V0C0j0C0C2g0j1c0j0j1v2g1v0j0j1v7N0j1c0j3L0j0j1v5Q1Z5Q1v4lfn1v420j1v5Q1Z5Q1v4l1v2z1v',
|
||||
'0H140r0N0r140r0u0r0V171c11140C0j0u110j0u0j1v0j0C0j0j0j0b080V0u080b0C1v0j0j0j0C0j0b080V0j0j0b080b0j0j0j0j0b080b0C080j0b080b0j0j0j0j0j0j0b080j0b080C0b080b080b080b0j0j0j0j080b0j0C0j0j0j0b0j0j080C0b0j0j0j0j0j0j0b08080b0j0C0j0j0j0b0j0j0K0b0j0C0j0j0j0b080b080j0C0b0j080b080b0j0j0j0j080b0j0b0r0j0j0j0b0j0C0r0b0j0j0j0j0j0j0j0b080j0b0r0C0j0b0j0j0j0r0b0j0C0j0j0j0u0r0b0C0j080b0j0j0j0j0j0j0j1c0j0b0j0j0j0C0j0j0j0j0j0j0j0b080j1c0u0j0j0j0C0j1c0j0u0j1c0j0j0j0j0j0j0j0j1c0j0u1v0j0j0V0j0j2g0j0j0j0C1v0C1G0j0j0V0C1Z1O0j0V0j0j2g1v0j0j0V0C2g5x1v4l1v421O7N0V0C4l1v2S1c0j1v2S2_',
|
||||
'050b080C0j0j0j0C0j0j0C0j0j0j0C0j0C0j0C030j0j0j0j0j0j0j0j0j0C0j0b080u0V080b0j0j0V0j0j0j0j0j0j0j0j0j0V0N0j0C0C0j0j0j0j0j0j0j0j1c0j0u0j1v0j0j0j0j0j0b080b080j0j0j0b080b080b080b080b0j0j0j080b0j0b080j0j0j0j0b080b0j0j0r0b080b0b080j0j0j0j0b080b080j0b080j0b080b080b080b080b0j0j0r0b0j0b080j0j0j0j0b080b0j0j0C080b0b080j0j0j0j0j0j0j0b080u080j0j0b0j0j0j0C0j0b080j0j0j0j0b080b080b080b0C080b080b080b0j0j0j0j0j0j0b0C080j0j0b0j0j0j0C0j0b080j0j0C0b080b080j0b0j0j0C080b0j0j0j0j0j0j0b0j0j080C0b0j080b0j0j0j0j0j0j0j0C0j0j0j0b0j0j0C080b0j0j0j0j0j0j0b080b080b0K0b080b080b0j0j0j0j0j0j0j0C0j0j0u0j0j0V0j080b0j0C0j0j0j0b0j0r0C0b0j0j0j0j0j0j0j0j0j0C0j0b080b080b0j0C0C0j0C0j0j0j0u110u0j0j0j0j0j0j0j0j0C0j0j0u0j1c0j0j0j0j0j0j0j0j0V0C0u0j0C0C0V0C1Z0j0j0j0C0j0j0j1v0u0j1c0j0j0j0C0j0j2g0j1c1v0C1Z0V0j4l0j0V0j0j2g0j1v0j1v2S1c7N1v',
|
||||
'0w0j1c0j0V0j0j0V0V0V0j0m0V0j0C1c140j0j0j0C0V0C0j1v0j0N0j0C0j0j0j0V0j0j1v0N0j0j0V0j0j0j0j0j0j080b0j0j0j0j0j0j0j080b0j0C0j0j0j0b0j0j080u080b0j0j0j0j0j0j0b080b080b080C0b0j080b080b0j0j0j0j080b0j0C0j0j0j0b0j0j080u080b0j0j0j0j0j0j0b080b080b080b0r0b0j080b080b0j0j0j0j080b0j0b0r0j0j0b080b0j0j080b0j080b0j080b080b0j0j0j0j0j0b080b0r0C0b080b0j0j0j0j080b0b080b080j0j0j0b080b080b080b0j0j0j0j080b0j0b080j0j0j0j0b080b0j0j0r0b080b0j0j0j0j0j0b080b080j0b0r0b080j0b080b0j0j0j0j080b0j0b080j0j0j0j0b080b0j080b0r0b0j080b080b0j0j0j0j0j0b080b0r0C0b080b0j0j0j0j0j0j0b080j0j0j0b080b080b080b0j0j0j0r0b0j0b080j0j0j0j0b080b0r0b0r0b0j080b080b0j0j0j0j0j0j0b0r0j0j0j0b0j0j0j0j080b0j0b080j0j0j0j0b080b080b0j0r0b0j080b0j0j0j0j0j0j0j0b0r0C0b0j0j0j0j0j0j0j080b0j0C0j0j0j0b0j0C0r0b0j0j0j0j0j0j0b080b080u0r0b0j080b0j0j0j0j0j0j0j0b0r0C0u0j0j0j0C0j080b0j0C0j0j0j0u110b0j0j0j0j0j0j0j0j0j0C0j0b080b0j0j0C0C0j0C0j0j0j0b0j1c0j080b0j0j0j0j0j0j0V0j0j0u0j1c0j0j0j0C0j0j2g0j0j0j0C0j0j0V0j0b080b1c0C0V0j0j2g0j0j0V0j0j1c0j1Z0j0j0C0C0j1v',
|
||||
'160j0j0V0j1c0j0C0j0C0j1f0j0V0C0j0j0C0j0j0j1G080b080u0V080b0j0j0V0j1v0j0u0j1c0j0j0j0C0j0j0j0C0C0j1D0b0j080b0j0j0j0j0C0j0b0r0C0j0b0j0C0C0j0j0j0j0j0j0j0j0j0b0r0b0r0j0b0j0j0j0C0j0b0r0j0j0j0b080b080j0b0C0j080b080b0j0j0j0j0j0j0b0C080j0j0b0j0j0j0C0j0b080j0j0j0j0b080b080j0b0C0r0j0b0j0j0j0j0j0j0b0C080j0j0b0j0j0j0C0j0j0j0j0C0j0j0b080b0j0j0C080b0j0j0j0j0j0j0b080b080b080C0b080b080b080b0j0j0j0j0j0b080C0j0j0b080b0j0j0C080b0j0j0j0j0j0j0b080j0b0C080j0j0b0j0j0j0j0j0j0b080j0b080C0b080b080b080b0j0j0j0j080b0j0C0j0j0b080b0j0j0C080b0j0j0j0j0j0j0b080j0b080u080j0j0b0j0j0j0j0j0j0b080C0j0j0b080b0j0j0C0j0j080b0j0j0j0j0j0b080b0C0r0b080b0j0j0j0j0j0j0b080j0b080u080b080b080b0j0j0j0C0j0b080j0j0j0j0b0j0j0j0C0j0j080b0j0j0j0j0j0b080b0C0r0b080b0j0j0j0j0j0j0b080j0b0r0b080b080b080b0j0j0j0r0b0j0b0r0j0j0j0b0j0j0j0r0b0j080b0j0j0j0j0j0j0j0b0r0C0b0j0j0j0j0j0j0j0b080j0C0u080b080b0j0j0j0r0b0j0C0C0j0b0j110b0j080b0j0j0j0j0j0j0u0r0C0b0j0j0j0j0j0j0j0j0j0C0j0j0j0b0j1c0j0C0j0j0j0b0j0814080b080b0j0j0j0j0j0j1c0j0u0j0j0V0j0j0j0j0j0j0j0u110u0j0j0j',
|
||||
'020b0r0C0j0j0j0C0j0j0V0j0j0j0j0j0C0j1f0j0C0j0V1G0j0j0j0j0V0C0j0C1v0u0j0j0j0V0j0j0C0j0j0j1v0N0C0V0j0j0j0K0C250b0C0V0j0j0V0j0j2g0C0V0j0j0C0j0j0b081v0N0j0j0V0V0j0j0u0j1c0j080b0j0j0j0j0j0j0V0j0j0u0j0j0V0j0j0j0C0j0b080b080V0b0j080b0j0j0j0j0j0j0j0b0r0C0j0b0j0j0j0C0j080b0j0j0j0j0j0j0u0r0C0u0j0j0j0j0j0j0b080j0C0j0b080b080b0j0C0j080b0j0j0j0j0j0j0b080b110b0j0j0j0j0j0j0j0j0j0b0r0j0j0j0b0j0j0j0r0b0j0b080j0j0j0j0b080b080b080b0r0b0j080b080b0j0j0j0j0j0j0b0r0C0b080b0j0j0j0j080b0j0b080j0j0j0j0b080b080b0j0j0j0r0b0j0j0j0j0j0j0b080b0j080C0b0j080b080b0j0j0j0j080b0j0b0r0C0b080b0j0j0j0j080b0j0j0j0j0j0b080b080b080b0j0j080b0r0b0j0j0j0j0j0j0b0j0j080C0b0j080b080b0j0j0j0j0j0b080C0j0j0b080b0j0j0C0j0b080j0j0j0j0b080b080b080b0C0C080b0j0j0j0j0j0j0b0C0C080b080b080b0j0j0j0j0j0j0b0C080j0j0b0j0j0j0C0j0b080j0b080j0j0b080b080b080b0C0r0b0j0j0j0j0j0j0b080b0r0b0r0b0j080b080b0j0j0j0j0j0j0b0r0C0j0b0j0j0j0j0j0j0b080j0C0j0b080j0b0j0j0K0b0j0C0j0j0j0b080b0j0K0b0j080b0j0j0j0j0j0j0V0j0j0b0j0j0j0C0j0j0j0j',
|
||||
'0l0C0K0N0r0N0j0r1G0V0m0j0V1c0C0j0j0j0j1O0N110u0j0j0j0C0j0j0V0C0j0u110u0j0j0j0C0j0j0j0C0C0j250j1c2S1v1v0j5x2g0j1c0j0j1c2z0j1c0j0j1c0j0N1v0V0C1v0C0b0C0V0j0j0C0j0C1v0u0j0C0C0j0j0j0C0j0j0j0u110u0j0j0j0C0j0C0C0C0b080b0j0C0j080b0j0C0j0j0j0u110u0j0j0j0C0j0j0j0C0j0j0j0u0C0r0u0j0j0j0j0j0j0b0r0b0V080b080b0j0C0j0j0j0V0j0j0b0j0j0j0C0j0j0j0j0j0j0j0b080j0b0C0r0j0b0j0j0j0C0j0b0r0b0r0j0b080b080b0j0C0j0j0j0j0j0j0j0j0b0j0C0r0b0j0j0j0j0j0j0b080b080j0b0r0b0r0j0b0j0j0j0j080b0j0b0r0j0j0j0b080b080b0j0j0j0j080b0j0j0j0j0j0j0b0j0j0j0r0b0j0j0j0j0j0j0b080b080b080b0r0C0b080b0j0j0j0j0j0b080b0r0C0b080b080b080b0j0j0j0j080b0j0C0j0j0j0b0j0j0C080b0j0j0j0j0j0j0b080j0b0C080j0j0b0j0j0j0j0j0j0b0r0b080j0j0b080b080b0j0j0j0j0j0j0b080j0j0j0j0b0j0j0j0r0b0j0b080j0j0j0j0j0b080b080b0C0r0b0j0j0j0j0j0j0b080b080j0C0b0j080b080b0j0j0j0j0j0j',
|
||||
'0a0j0j0j0j0C0j0j0C0j0C0C0j0j0j0j0j0j0j0m0C0j0j0j0j0u080j0j0j1n0j0j0j0j0C0j0j0j0V0j0j0j1c0u0j0C0V0j0j0V0j0j1v0N0C0V2o1v1O2S2o141v0j1v4l0j1c0j1v2S2o0C0u1v0j0C0C2S1v0j1c0j0j1v0N251c0j1v0b1c1v1n1v0j0j0V0j0j1v0N1v0C0V0j0j1v0b0C0j0j0V1c0j0u0j1c0j0j0j0j0j0j0j0j1c0j0u0j0j0V0j0j0j0j0j0j0b080u110u0j0j0j0j0j0j1c0j0b0j080b0j0C0j0j0j0V0j0j0u0C0V0j0j0j0C0j0b080j1c0j0b0j0j0j0C0j0C0j0j0j0b080b080b0j0C0j080b0j0j0j0j0j0j0j0b0C0r0u0j0j0j0j0j0j0b080j0b0r0C0j0b0j0j0j0r0b0j0b0r0j0j0j0b080b080b0j0r0b0j080b0j0j0j0j0j0j0b0j0r0C0b0j0j0j0j0j0j0b080j0j0C0j0j0b080b0j0j0j0j0j0j0j0j0j0j0b080b080b080b0C0j0j080b0j0j0j0j0j0j0b0j0j0C080b0j0j0j0j0j0j0j0j0b0C080j0j0b0j0j0j0j0j',
|
||||
'0n0Q0j1c14010q0V1c171k0u0r140V0j0j1c0C0N1O0j0V0j0j0j1c0j0u110u0C0j0C0V0C0j0j0b671v0j1v5Q1O2S2o2S1v4l1v0j1v2S2o0C1Z0j0C0C1O141v0j1c0j2z1O0j0V0j0j1v0b2H390j1c0j0V0C2z0j1c0j1v2g0C0V0j1O0b0j0j0V0C1c0j0u0j1c0j0j0j0j0j0j0j0j1c0N0j0j0V0j0j0C0j0j0b081v0u0j0j0j0C0j1c0N0j0j0C0j0j0j0C0j0j0j0u0C0r0u0j0j0j0C0j0b080j1c0j0b0j0C0C0j0C0C0j0b080b080u0C0j080b0j0C0j0j0j0u110u0j0j0j0j0j0j0j0j0C0C0j0b0j0j0j0C0j0C0C0j0b080b080b0j0C0j080b0j0C0j0j0j0b0j110b0j0j0j0j0j',
|
||||
'0B0j0V0j0j0C0j0j0j0C0j0C0j0j0C0j0m0j0j0j0j0C0j0C0j0j0u0j1c0j0j0C0C0j0j0j0j0j0j0j0j0u110N0j0j0V0C0V0j0b081n080b0CrU1O5e2SbX2_1Z0V2o141v0j0C0C0j2z1v0j1c0j7N1O420j1c0j1v2S1c0j1v2S2_0b0j0V0j0j1v0N1v0j0j1c0j1v140j0V0j0j0C0C0b080u1v0C0V0u110u0j0j0j0C0j0j0j0C0C0N0C0V0j0j0C0j0j0b080u110u0C0j0C0u0r0C0u080b0j0j0C0j0j0j'
|
||||
]
|
||||
for m in months:
|
||||
n: int = 0
|
||||
size: int = int(m.__len__() / 2)
|
||||
l: List[int] = []
|
||||
for y in range(0, size):
|
||||
z: int = y * 2
|
||||
t: int = 0
|
||||
c: int = 1
|
||||
for x in range(1, -1, -1):
|
||||
t += c * chars.index(m[z + x])
|
||||
c *= 64
|
||||
n += t
|
||||
l.append(n)
|
||||
LunarYear._LEAP.append(l)
|
||||
LunarYear._IS_INIT = True
|
||||
|
||||
@staticmethod
|
||||
def validate(year: int) -> None:
|
||||
if year < -1 or year > 9999:
|
||||
raise ValueError(f'illegal lunar year: {year}')
|
||||
|
||||
def __init__(self, year: int):
|
||||
LunarYear._init()
|
||||
LunarYear.validate(year)
|
||||
super().__init__(year)
|
||||
|
||||
@classmethod
|
||||
def from_year(cls, year: int) -> LunarYear:
|
||||
return cls(year)
|
||||
|
||||
def get_day_count(self) -> int:
|
||||
"""
|
||||
当年的总天数
|
||||
:return: 数字,从正月初一到除夕的总天数
|
||||
"""
|
||||
n: int = 0
|
||||
months: List[LunarMonth] = self.get_months()
|
||||
for i in range(0, months.__len__()):
|
||||
n += months[i].get_day_count()
|
||||
return n
|
||||
|
||||
def get_month_count(self) -> int:
|
||||
"""
|
||||
当年的总月数
|
||||
:return: 数字,有闰月为13,无闰月为12
|
||||
"""
|
||||
return 12 if self.get_leap_month() < 1 else 13
|
||||
|
||||
def get_name(self) -> str:
|
||||
"""
|
||||
:return: 农历{六十甲子}年
|
||||
"""
|
||||
return f'农历{self.get_sixty_cycle().get_name()}年'
|
||||
|
||||
def next(self, n: int) -> LunarYear:
|
||||
return LunarYear(self._year + n)
|
||||
|
||||
def get_leap_month(self) -> int:
|
||||
"""
|
||||
当年的闰月月份
|
||||
:return: 数字,代表当年的闰月月份,例如:5代表闰五月,0代表当年没有闰月
|
||||
"""
|
||||
if self._year == -1:
|
||||
return 11
|
||||
for i in range(0, self._LEAP.__len__()):
|
||||
if self._year in self._LEAP[i]:
|
||||
return i + 1
|
||||
return 0
|
||||
|
||||
def get_sixty_cycle(self) -> SixtyCycle:
|
||||
"""
|
||||
当年的干支
|
||||
:return: 干支 SixtyCycle
|
||||
"""
|
||||
from tyme4py.sixtycycle import SixtyCycle
|
||||
return SixtyCycle(self._year - 4)
|
||||
|
||||
def get_twenty(self) -> Twenty:
|
||||
"""
|
||||
:return: 运 Twenty
|
||||
"""
|
||||
return Twenty(floor((self._year - 1864) / 20))
|
||||
|
||||
def get_nine_star(self) -> NineStar:
|
||||
"""
|
||||
:return: 九星 NineStar
|
||||
"""
|
||||
return NineStar(63 + self.get_twenty().get_sixty().get_index() * 3 - self.get_sixty_cycle().get_index())
|
||||
|
||||
def get_jupiter_direction(self) -> Direction:
|
||||
"""
|
||||
太岁方位
|
||||
:return: 方位 Direction
|
||||
"""
|
||||
return Direction([0, 7, 7, 2, 3, 3, 8, 1, 1, 6, 0, 0][self.get_sixty_cycle().get_earth_branch().get_index()])
|
||||
|
||||
def get_first_month(self) -> LunarMonth:
|
||||
"""
|
||||
首月(农历月,即一月,俗称正月)
|
||||
:return: 农历月
|
||||
"""
|
||||
return LunarMonth.from_ym(self._year, 1)
|
||||
|
||||
def get_months(self) -> List[LunarMonth]:
|
||||
"""
|
||||
农历月列表
|
||||
:return: 农历月 LunarMonth 的列表,从正月到十二月,包含闰月
|
||||
"""
|
||||
l: List[LunarMonth] = []
|
||||
leap_month: int = self.get_leap_month()
|
||||
for i in range(1, 13):
|
||||
l.append(LunarMonth.from_ym(self._year, i))
|
||||
if i == leap_month:
|
||||
l.append(LunarMonth.from_ym(self._year, -i))
|
||||
return l
|
||||
|
||||
def get_kitchen_god_steed(self) -> KitchenGodSteed:
|
||||
"""
|
||||
灶马头
|
||||
:return: 灶马头
|
||||
"""
|
||||
return KitchenGodSteed.from_lunar_year(self._year)
|
||||
|
||||
|
||||
class LunarSeason(LoopTyme):
|
||||
"""
|
||||
农历季节
|
||||
从正月开始,依次为:孟春、仲春、季春、孟夏、仲夏、季夏、孟秋、仲秋、季秋、孟冬、仲冬、季冬。
|
||||
"""
|
||||
NAMES: List[str] = ['孟春', '仲春', '季春', '孟夏', '仲夏', '季夏', '孟秋', '仲秋', '季秋', '孟冬', '仲冬', '季冬']
|
||||
"""名称"""
|
||||
|
||||
def __init__(self, index_or_name: Union[int, str]):
|
||||
super().__init__(self.NAMES, index_or_name)
|
||||
|
||||
@classmethod
|
||||
def from_name(cls, name: str) -> LunarSeason:
|
||||
return cls(name)
|
||||
|
||||
@classmethod
|
||||
def from_index(cls, index: int) -> LunarSeason:
|
||||
return cls(index)
|
||||
|
||||
def next(self, n: int) -> LunarSeason:
|
||||
return LunarSeason(self.next_index(n))
|
||||
|
||||
|
||||
class LunarMonth(MonthUnit):
|
||||
"""
|
||||
农历月
|
||||
农历月以初一开始,大月30天,小月29天
|
||||
"""
|
||||
NAMES: List[str] = ['正月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月']
|
||||
|
||||
@staticmethod
|
||||
def validate(year: int, month: int) -> None:
|
||||
if month == 0 or month > 12 or month < -12:
|
||||
raise ValueError(f'illegal lunar month: {month}')
|
||||
if month < 0 and -month != LunarYear.from_year(year).get_leap_month():
|
||||
raise ValueError(f'illegal leap month {-month} in lunar year {year}')
|
||||
|
||||
def __init__(self, year: int, month: int):
|
||||
"""
|
||||
:param year: 农历年
|
||||
:param month: 农历月,闰月为负
|
||||
"""
|
||||
LunarMonth.validate(year, month)
|
||||
super().__init__(year, abs(month))
|
||||
self._leap = month < 0
|
||||
|
||||
@classmethod
|
||||
def from_ym(cls, year: int, month: int) -> LunarMonth:
|
||||
"""
|
||||
从农历年、月初始化
|
||||
:param year: 农历年,支持从-1到9999年
|
||||
:param month: 农历月,支持1到12,如果为闰月的,使用负数,即-3代表闰三月
|
||||
:return: LunarMonth
|
||||
"""
|
||||
return cls(year, month)
|
||||
|
||||
def _get_new_moon(self):
|
||||
from tyme4py.solar import SolarTerm
|
||||
# 冬至
|
||||
dong_zhi_jd: float = SolarTerm(self._year, 0).get_cursory_julian_day()
|
||||
# 冬至前的初一,今年首朔的日月黄经差
|
||||
w: int = ShouXingUtil.calc_shuo(dong_zhi_jd)
|
||||
if w > dong_zhi_jd:
|
||||
w -= 29.53
|
||||
|
||||
# 正常情况正月初一为第3个朔日,但有些特殊的
|
||||
offset: int = 2
|
||||
if 8 < self._year < 24:
|
||||
offset = 1
|
||||
elif LunarYear(self._year - 1).get_leap_month() > 10 and self._year != 239 and self._year != 240:
|
||||
offset = 3
|
||||
# 本月初一
|
||||
return w + 29.5306 * (offset + self.get_index_in_year())
|
||||
|
||||
def get_lunar_year(self) -> LunarYear:
|
||||
"""
|
||||
农历年
|
||||
:return: 农历年
|
||||
"""
|
||||
return LunarYear.from_year(self._year)
|
||||
|
||||
def get_month_with_leap(self) -> int:
|
||||
"""
|
||||
月(支持闰月)
|
||||
:return: 月份数字,范围为1到12,闰月为负数,如闰7月返回-7
|
||||
"""
|
||||
return -self._month if self._leap else self._month
|
||||
|
||||
def get_day_count(self) -> int:
|
||||
"""
|
||||
当月的总天数
|
||||
:return: 数字,从初一开始的总天数,大月有30天,小月有29天
|
||||
"""
|
||||
w: float = self._get_new_moon()
|
||||
return ~~(ShouXingUtil.calc_shuo(w + 29.5306) - ShouXingUtil.calc_shuo(w))
|
||||
|
||||
def get_index_in_year(self) -> int:
|
||||
"""
|
||||
位于当年的月索引
|
||||
:return: 数字,范围0到12,正月为0,依次类推,例如五月索引值为4,闰五月索引值为5
|
||||
"""
|
||||
# 位于当年的索引
|
||||
index: int = self._month - 1
|
||||
if self._leap:
|
||||
index += 1
|
||||
else:
|
||||
leap_month: int = LunarYear.from_year(self._year).get_leap_month()
|
||||
if 0 < leap_month < self._month:
|
||||
index += 1
|
||||
return index
|
||||
|
||||
def get_season(self) -> LunarSeason:
|
||||
"""
|
||||
:return: 农历季节
|
||||
"""
|
||||
return LunarSeason(self._month - 1)
|
||||
|
||||
def get_first_julian_day(self) -> JulianDay:
|
||||
"""
|
||||
初一的儒略日
|
||||
:return: 儒略日
|
||||
"""
|
||||
from tyme4py.jd import JulianDay
|
||||
return JulianDay.from_julian_day(JulianDay.J2000 + ShouXingUtil.calc_shuo(self._get_new_moon()))
|
||||
|
||||
def is_leap(self) -> bool:
|
||||
"""
|
||||
是否闰月
|
||||
:return: 布尔值,闰月返回true,非闰月返回false
|
||||
"""
|
||||
return self._leap
|
||||
|
||||
def get_week_count(self, start: int) -> int:
|
||||
"""
|
||||
当月有几周
|
||||
:param start: 参数为起始星期,1234560分别代表星期一至星期天
|
||||
:return: 数字
|
||||
"""
|
||||
return ceil((self.index_of(self.get_first_julian_day().get_week().get_index() - start, 7) + self.get_day_count()) / 7)
|
||||
|
||||
def get_name(self) -> str:
|
||||
"""
|
||||
依据国家标准《农历的编算和颁行》GB/T 33661-2017中农历月的命名方法。
|
||||
:return: 名称
|
||||
"""
|
||||
return ('闰' if self._leap else '') + self.NAMES[self._month - 1]
|
||||
|
||||
def __str__(self) -> str:
|
||||
return f'{self.get_lunar_year()}{self.get_name()}'
|
||||
|
||||
def next(self, n: int) -> LunarMonth:
|
||||
if n == 0:
|
||||
return LunarMonth.from_ym(self._year, self.get_month_with_leap())
|
||||
|
||||
m: int = self.get_index_in_year() + 1 + n
|
||||
y: LunarYear = self.get_lunar_year()
|
||||
if n > 0:
|
||||
month_count: int = y.get_month_count()
|
||||
while m > month_count:
|
||||
m -= month_count
|
||||
y = y.next(1)
|
||||
month_count = y.get_month_count()
|
||||
else:
|
||||
while m <= 0:
|
||||
y = y.next(-1)
|
||||
m += y.get_month_count()
|
||||
|
||||
leap: bool = False
|
||||
leap_month: int = y.get_leap_month()
|
||||
if leap_month > 0:
|
||||
if m == leap_month + 1:
|
||||
leap = True
|
||||
if m > leap_month:
|
||||
m -= 1
|
||||
return LunarMonth.from_ym(y.get_year(), -m if leap else m)
|
||||
|
||||
def get_days(self) -> List[LunarDay]:
|
||||
"""
|
||||
本月的农历日列表
|
||||
:return: 农历日 LunarDay 的列表,从初一开始
|
||||
"""
|
||||
m: int = self.get_month_with_leap()
|
||||
l: List[LunarDay] = []
|
||||
for i in range(1, self.get_day_count() + 1):
|
||||
l.append(LunarDay(self._year, m, i))
|
||||
return l
|
||||
|
||||
def get_first_day(self) -> LunarDay:
|
||||
"""
|
||||
初一
|
||||
"""
|
||||
return LunarDay.from_ymd(self._year, self.get_month_with_leap(), 1)
|
||||
|
||||
def get_weeks(self, start: int) -> List[LunarWeek]:
|
||||
"""
|
||||
本月的农历周列表
|
||||
:param start: 参数为起始星期,1234560分别代表星期一至星期天
|
||||
:return: 农历周 LunarWeek 的列表
|
||||
"""
|
||||
m: int = self.get_month_with_leap()
|
||||
l: List[LunarWeek] = []
|
||||
for i in range(0, self.get_week_count(start)):
|
||||
l.append(LunarWeek(self._year, m, i, start))
|
||||
return l
|
||||
|
||||
def get_sixty_cycle(self) -> SixtyCycle:
|
||||
"""
|
||||
当月的干支
|
||||
:return: 干支 SixtyCycle
|
||||
"""
|
||||
from tyme4py.sixtycycle import SixtyCycle
|
||||
return SixtyCycle.from_index(self._year * 12 + self._month - 47)
|
||||
|
||||
def get_nine_star(self) -> NineStar:
|
||||
"""
|
||||
:return: 九星 NineStar
|
||||
"""
|
||||
index = self.get_sixty_cycle().get_earth_branch().get_index()
|
||||
if index < 2:
|
||||
index += 3
|
||||
return NineStar(27 - self.get_lunar_year().get_sixty_cycle().get_earth_branch().get_index() % 3 * 3 - index)
|
||||
|
||||
def get_jupiter_direction(self) -> Direction:
|
||||
"""
|
||||
太岁方位
|
||||
:return: 方位 Direction
|
||||
"""
|
||||
from tyme4py.sixtycycle import SixtyCycle
|
||||
sixty_cycle: SixtyCycle = self.get_sixty_cycle()
|
||||
n: int = [7, -1, 1, 3][sixty_cycle.get_earth_branch().next(-2).get_index() % 4]
|
||||
return Direction(n) if n != -1 else sixty_cycle.get_heaven_stem().get_direction()
|
||||
|
||||
def get_fetus(self) -> Union[FetusMonth, None]:
|
||||
"""
|
||||
:return: 逐月胎神 FetusMonth。闰月无胎神。
|
||||
"""
|
||||
return FetusMonth.from_lunar_month(self)
|
||||
|
||||
def get_minor_ren(self) -> MinorRen:
|
||||
"""
|
||||
:return: 小六壬
|
||||
"""
|
||||
return MinorRen((self._month - 1) % 6)
|
||||
|
||||
|
||||
class LunarWeek(WeekUnit):
|
||||
"""
|
||||
农历周
|
||||
农历一个月最多有6个周,分别为:第一周、第二周、第三周、第四周、第五周、第六周。
|
||||
"""
|
||||
|
||||
@staticmethod
|
||||
def validate(year: int, month: int, index: int, start: int) -> None:
|
||||
WeekUnit.validate(year, month, index, start)
|
||||
m: LunarMonth = LunarMonth.from_ym(year, month)
|
||||
if index >= m.get_week_count(start):
|
||||
raise ValueError(f'illegal lunar week index: {index} in month: {m}')
|
||||
|
||||
def __init__(self, year: int, month: int, index: int, start: int):
|
||||
"""
|
||||
:param year: 年
|
||||
:param month: 月
|
||||
:param index: 周索引,0-5
|
||||
:param start: 起始星期 (1234560分别代表星期一至星期日)
|
||||
"""
|
||||
LunarWeek.validate(year, month, index, start)
|
||||
super().__init__(year, month, index, start)
|
||||
|
||||
@classmethod
|
||||
def from_ym(cls, year: int, month: int, index: int, start: int) -> LunarWeek:
|
||||
return cls(year, month, index, start)
|
||||
|
||||
def get_lunar_month(self) -> LunarMonth:
|
||||
"""
|
||||
:return:农历月
|
||||
"""
|
||||
return LunarMonth.from_ym(self._year, self._month)
|
||||
|
||||
def get_name(self) -> str:
|
||||
return self.NAMES[self._index]
|
||||
|
||||
def __str__(self) -> str:
|
||||
return f'{self.get_lunar_month()}{self.get_name()}'
|
||||
|
||||
def next(self, n: int) -> LunarWeek:
|
||||
d: int = self._index + n
|
||||
m: LunarMonth = self.get_lunar_month()
|
||||
if n > 0:
|
||||
week_count: int = m.get_week_count(self._start)
|
||||
while d >= week_count:
|
||||
d -= week_count
|
||||
m = m.next(1)
|
||||
if m.get_first_day().get_week().get_index() != self._start:
|
||||
d += 1
|
||||
week_count = m.get_week_count(self._start)
|
||||
else:
|
||||
while d < 0:
|
||||
if m.get_first_day().get_week().get_index() != self._start:
|
||||
d -= 1
|
||||
m = m.next(-1)
|
||||
d += m.get_week_count(self._start)
|
||||
return LunarWeek(m.get_year(), m.get_month_with_leap(), d, self._start)
|
||||
|
||||
def get_first_day(self) -> LunarDay:
|
||||
"""
|
||||
本周第一天的农历日
|
||||
:return: 农历日 LunarDay
|
||||
"""
|
||||
first_day: LunarDay = LunarDay(self._year, self._month, 1)
|
||||
return first_day.next(self._index * 7 - self.index_of(first_day.get_week().get_index() - self._start, 7))
|
||||
|
||||
def get_days(self) -> List[LunarDay]:
|
||||
"""
|
||||
本周农历日列表
|
||||
:return: 农历日 LunarDay的列表
|
||||
"""
|
||||
l: List[LunarDay] = []
|
||||
d: LunarDay = self.get_first_day()
|
||||
l.append(d)
|
||||
for i in range(1, 7):
|
||||
l.append(d.next(i))
|
||||
return l
|
||||
|
||||
def __eq__(self, other: LunarWeek) -> bool:
|
||||
return other and other.get_first_day() == self.get_first_day()
|
||||
|
||||
|
||||
class LunarDay(DayUnit):
|
||||
"""农历日"""
|
||||
NAMES: List[str] = ['初一', '初二', '初三', '初四', '初五', '初六', '初七', '初八', '初九', '初十', '十一', '十二', '十三', '十四', '十五', '十六', '十七', '十八', '十九', '二十', '廿一', '廿二', '廿三', '廿四', '廿五', '廿六', '廿七', '廿八', '廿九', '三十']
|
||||
"""名称"""
|
||||
|
||||
@staticmethod
|
||||
def validate(year: int, month: int, day: int) -> None:
|
||||
if day < 1:
|
||||
raise ValueError(f'illegal lunar day {day}')
|
||||
m: LunarMonth = LunarMonth.from_ym(year, month)
|
||||
if day > m.get_day_count():
|
||||
raise ValueError(f'illegal day {day} in {m}')
|
||||
|
||||
def __init__(self, year: int, month: int, day: int):
|
||||
"""
|
||||
:param year: 农历年
|
||||
:param month: 农历月,闰月为负
|
||||
:param day: 农历日
|
||||
"""
|
||||
LunarDay.validate(year, month, day)
|
||||
super().__init__(year, month, day)
|
||||
|
||||
@classmethod
|
||||
def from_ymd(cls, year: int, month: int, day: int) -> LunarDay:
|
||||
return cls(year, month, day)
|
||||
|
||||
def get_lunar_month(self) -> LunarMonth:
|
||||
"""
|
||||
:return: 农历月
|
||||
"""
|
||||
return LunarMonth.from_ym(self._year, self._month)
|
||||
|
||||
def get_name(self) -> str:
|
||||
"""
|
||||
:return: 农历日名,如:初一
|
||||
"""
|
||||
return self.NAMES[self._day - 1]
|
||||
|
||||
def __str__(self) -> str:
|
||||
return f'{self.get_lunar_month()}{self.get_name()}'
|
||||
|
||||
def next(self, n: int) -> LunarDay:
|
||||
return self.get_solar_day().next(n).get_lunar_day()
|
||||
|
||||
def is_before(self, target: LunarDay) -> bool:
|
||||
"""
|
||||
是否在指定农历日之前
|
||||
:param target: 农历日 LunarDay
|
||||
:return: true/false
|
||||
"""
|
||||
y: int = target.get_year()
|
||||
if self._year != y:
|
||||
return self._year < y
|
||||
m: int = target.get_month()
|
||||
if self._month != m:
|
||||
t: int = abs(m)
|
||||
return self._month == t or abs(self._month) < t
|
||||
return self._day < target.get_day()
|
||||
|
||||
def is_after(self, target: LunarDay) -> bool:
|
||||
"""
|
||||
是否在指定农历日之后
|
||||
:param target: 农历日 LunarDay
|
||||
:return:
|
||||
"""
|
||||
y: int = target.get_year()
|
||||
if self._year != y:
|
||||
return self._year > y
|
||||
m: int = target.get_month()
|
||||
if self._month != m:
|
||||
t: int = abs(self._month)
|
||||
return t == m or t > abs(m)
|
||||
return self._day > target.get_day()
|
||||
|
||||
def get_week(self) -> Week:
|
||||
"""
|
||||
:return: 星期
|
||||
"""
|
||||
return self.get_solar_day().get_week()
|
||||
|
||||
def get_year_sixty_cycle(self) -> SixtyCycle:
|
||||
"""
|
||||
当天的年干支 非当天所属的农历年干支,以立春换年。
|
||||
:return: 干支 SixtyCycle
|
||||
"""
|
||||
warnings.warn('get_year_sixty_cycle() is deprecated, please use SixtyCycleDay.get_year() instead.', DeprecationWarning)
|
||||
return self.get_sixty_cycle_day().get_year()
|
||||
|
||||
def get_month_sixty_cycle(self) -> SixtyCycle:
|
||||
"""
|
||||
当天的月干支 非当天所属的农历月干支,以节令换月。
|
||||
:return: 干支 SixtyCycle
|
||||
"""
|
||||
warnings.warn('get_month_sixty_cycle() is deprecated, please use SixtyCycleDay.get_month() instead.', DeprecationWarning)
|
||||
return self.get_sixty_cycle_day().get_month()
|
||||
|
||||
def get_sixty_cycle(self) -> SixtyCycle:
|
||||
"""
|
||||
当天的干支
|
||||
:return: 干支
|
||||
"""
|
||||
from tyme4py.sixtycycle import SixtyCycle
|
||||
return SixtyCycle.from_index(int(self.get_lunar_month().get_first_julian_day().next(self._day - 12).get_day()))
|
||||
|
||||
def get_duty(self) -> Duty:
|
||||
"""
|
||||
建除十二值神
|
||||
:return: 建除十二值神 Duty
|
||||
"""
|
||||
return self.get_sixty_cycle_day().get_duty()
|
||||
|
||||
def get_twelve_star(self) -> TwelveStar:
|
||||
"""
|
||||
黄道黑道十二神
|
||||
:return: 黄道黑道十二神 TwelveStar
|
||||
"""
|
||||
return self.get_sixty_cycle_day().get_twelve_star()
|
||||
|
||||
def get_nine_star(self) -> NineStar:
|
||||
"""
|
||||
:return: 九星 NineStar
|
||||
"""
|
||||
return self.get_solar_day().get_nine_star()
|
||||
|
||||
def get_jupiter_direction(self) -> Direction:
|
||||
"""
|
||||
太岁方位
|
||||
:return: 方位 Direction
|
||||
"""
|
||||
index: int = self.get_sixty_cycle().get_index()
|
||||
from tyme4py.culture import Element
|
||||
return Element(index // 12).get_direction() if index % 12 < 6 else self.get_lunar_month().get_lunar_year().get_jupiter_direction()
|
||||
|
||||
def get_fetus_day(self) -> FetusDay:
|
||||
"""
|
||||
:return:逐日胎神 FetusDay
|
||||
"""
|
||||
return FetusDay.from_lunar_day(self)
|
||||
|
||||
def get_phase_day(self) -> PhaseDay:
|
||||
"""
|
||||
月相第几天
|
||||
:return: 月相第几天
|
||||
"""
|
||||
today = self.get_solar_day()
|
||||
m = self.get_lunar_month().next(1)
|
||||
p = Phase.from_index(m.get_year(), m.get_month_with_leap(), 0)
|
||||
d = p.get_solar_day()
|
||||
while d.is_after(today):
|
||||
p = p.next(-1)
|
||||
d = p.get_solar_day()
|
||||
return PhaseDay(p, today.subtract(d))
|
||||
|
||||
def get_phase(self) -> Phase:
|
||||
"""
|
||||
月相
|
||||
:return: 月相 Phase
|
||||
"""
|
||||
return self.get_phase_day().get_phase()
|
||||
|
||||
def get_solar_day(self) -> SolarDay:
|
||||
"""
|
||||
公历日
|
||||
:return: 公历日 SolarDay
|
||||
"""
|
||||
return self.get_lunar_month().get_first_julian_day().next(self._day - 1).get_solar_day()
|
||||
|
||||
def get_sixty_cycle_day(self) -> SixtyCycleDay:
|
||||
"""
|
||||
干支日
|
||||
:return: 干支日
|
||||
"""
|
||||
return self.get_solar_day().get_sixty_cycle_day()
|
||||
|
||||
def get_twenty_eight_star(self) -> TwentyEightStar:
|
||||
"""
|
||||
:return: 二十八宿 TwentyEightStar
|
||||
"""
|
||||
return TwentyEightStar(10 + 8 * self.get_week().get_index()).next(-7 * self.get_sixty_cycle().get_earth_branch().get_index())
|
||||
|
||||
def get_festival(self) -> Union[LunarFestival, None]:
|
||||
"""
|
||||
农历传统节日,如果当天不是农历传统节日,返回None
|
||||
:return:农历传统节日 LunarFestival
|
||||
"""
|
||||
return LunarFestival.from_ymd(self._year, self._month, self._day)
|
||||
|
||||
def get_six_star(self) -> SixStar:
|
||||
"""
|
||||
:return: 六曜
|
||||
"""
|
||||
return SixStar((abs(self._month) + self._day - 2) % 6)
|
||||
|
||||
def get_gods(self) -> List[God]:
|
||||
"""
|
||||
神煞列表(吉神宜趋,凶神宜忌)
|
||||
:return: 神煞列表
|
||||
"""
|
||||
return self.get_sixty_cycle_day().get_gods()
|
||||
|
||||
def get_recommends(self) -> List[Taboo]:
|
||||
"""
|
||||
今日 宜
|
||||
:return: 宜忌列表
|
||||
"""
|
||||
return self.get_sixty_cycle_day().get_recommends()
|
||||
|
||||
def get_avoids(self) -> List[Taboo]:
|
||||
"""
|
||||
今日 忌
|
||||
:return: 宜忌列表
|
||||
"""
|
||||
return self.get_sixty_cycle_day().get_avoids()
|
||||
|
||||
def get_hours(self) -> List[LunarHour]:
|
||||
"""
|
||||
当天的时辰列表
|
||||
:return: 由于23:00-23:59、00:00-00:59均为子时,而农历日是从00:00-23:59为一天,所以获取当天的时辰列表,实际会返回13个。
|
||||
"""
|
||||
l: List[LunarHour] = [LunarHour(self._year, self._month, self._day, 0, 0, 0)]
|
||||
for i in range(0, 24, 2):
|
||||
l.append(LunarHour(self._year, self._month, self._day, i + 1, 0, 0))
|
||||
return l
|
||||
|
||||
def get_minor_ren(self) -> MinorRen:
|
||||
"""
|
||||
小六壬
|
||||
:return: 小六壬
|
||||
"""
|
||||
return self.get_lunar_month().get_minor_ren().next(self._day - 1)
|
||||
|
||||
def get_three_pillars(self) -> ThreePillars:
|
||||
"""
|
||||
三柱
|
||||
@return: 三柱
|
||||
"""
|
||||
return self.get_sixty_cycle_day().get_three_pillars()
|
||||
|
||||
|
||||
class LunarHour(SecondUnit):
|
||||
"""
|
||||
农历时辰
|
||||
"""
|
||||
provider: EightCharProvider = DefaultEightCharProvider()
|
||||
"""八字计算接口"""
|
||||
|
||||
@staticmethod
|
||||
def validate(year: int, month: int, day: int, hour: int, minute: int, second: int) -> None:
|
||||
SecondUnit.validate(year, month, day, hour, minute, second)
|
||||
LunarDay.validate(year, month, day)
|
||||
|
||||
def __init__(self, year: int, month: int, day: int, hour: int, minute: int = 0, second: int = 0):
|
||||
"""
|
||||
:param year: 农历年,支持从-1到9999年
|
||||
:param month: 农历月,支持1到12,如果为闰月的,使用负数,即-3代表闰三月
|
||||
:param day: 农历日,支持1到30,大月30天,小月29天
|
||||
:param hour: 时为0-23
|
||||
:param minute: 分为0-59
|
||||
:param second: 秒为0-59
|
||||
"""
|
||||
LunarHour.validate(year, month, day, hour, minute, second)
|
||||
super().__init__(year, month, day, hour, minute, second)
|
||||
|
||||
@classmethod
|
||||
def from_ymd_hms(cls, year: int, month: int, day: int, hour: int, minute: int = 0, second: int = 0) -> LunarHour:
|
||||
return cls(year, month, day, hour, minute, second)
|
||||
|
||||
def get_lunar_day(self) -> LunarDay:
|
||||
"""
|
||||
:return: 农历日
|
||||
"""
|
||||
return LunarDay.from_ymd(self._year, self._month, self._day)
|
||||
|
||||
def get_name(self) -> str:
|
||||
from tyme4py.sixtycycle import EarthBranch
|
||||
return f'{EarthBranch(self.get_index_in_day()).get_name()}时'
|
||||
|
||||
def __str__(self) -> str:
|
||||
return f'{self.get_lunar_day()}{self.get_sixty_cycle().get_name()}时'
|
||||
|
||||
def get_index_in_day(self) -> int:
|
||||
"""
|
||||
位于当天的索引
|
||||
:return: 数字,范围0到11
|
||||
"""
|
||||
return int((self._hour + 1) / 2)
|
||||
|
||||
def next(self, n: int) -> LunarHour:
|
||||
if n == 0:
|
||||
return LunarHour(self._year, self._month, self._day, self._hour, self._minute, self._second)
|
||||
h: int = self._hour + n * 2
|
||||
diff: int = -1 if h < 0 else 1
|
||||
hour: int = abs(h)
|
||||
days: int = int(hour / 24) * diff
|
||||
hour = (hour % 24) * diff
|
||||
if hour < 0:
|
||||
hour += 24
|
||||
days -= 1
|
||||
d: LunarDay = self.get_lunar_day().next(days)
|
||||
return LunarHour(d.get_year(), d.get_month(), d.get_day(), hour, self._minute, self._second)
|
||||
|
||||
def is_before(self, target: LunarHour) -> bool:
|
||||
"""
|
||||
是否在指定农历时辰之前
|
||||
:param target: 农历时辰
|
||||
:return: true/false
|
||||
"""
|
||||
a_day: LunarDay = self.get_lunar_day()
|
||||
b_day: LunarDay = target.get_lunar_day()
|
||||
if a_day != b_day:
|
||||
return a_day.is_before(b_day)
|
||||
h = target.get_hour()
|
||||
if self._hour != h:
|
||||
return self._hour < h
|
||||
m = target.get_minute()
|
||||
return self._minute < m if self._minute != m else self._second < target.get_second()
|
||||
|
||||
def is_after(self, target: LunarHour) -> bool:
|
||||
"""
|
||||
是否在指定农历时辰之后
|
||||
:param target: 农历时辰
|
||||
:return: true/false
|
||||
"""
|
||||
a_day: LunarDay = self.get_lunar_day()
|
||||
b_day: LunarDay = target.get_lunar_day()
|
||||
if a_day != b_day:
|
||||
return a_day.is_after(b_day)
|
||||
h = target.get_hour()
|
||||
if self._hour != h:
|
||||
return self._hour > h
|
||||
m = target.get_minute()
|
||||
return self._minute > m if self._minute != m else self._second > target.get_second()
|
||||
|
||||
def get_year_sixty_cycle(self) -> SixtyCycle:
|
||||
"""
|
||||
当时的年干支 非当时所属的农历年干支
|
||||
:return: 干支 SixtyCycle
|
||||
"""
|
||||
warnings.warn('get_year_sixty_cycle() is deprecated, please use SixtyCycleHour.get_year() instead.', DeprecationWarning)
|
||||
return self.get_sixty_cycle_hour().get_year()
|
||||
|
||||
def get_month_sixty_cycle(self) -> SixtyCycle:
|
||||
"""
|
||||
当时的月干支 非当天所属的农历月干支,以节令具体时刻换月。
|
||||
:return: 干支 SixtyCycle
|
||||
"""
|
||||
warnings.warn('get_year_sixty_cycle() is deprecated, please use SixtyCycleHour.get_month() instead.', DeprecationWarning)
|
||||
return self.get_sixty_cycle_hour().get_month()
|
||||
|
||||
def get_day_sixty_cycle(self) -> SixtyCycle:
|
||||
"""
|
||||
当时的日干支
|
||||
:return: 干支 SixtyCycle。注意:23:00开始算做第二天。
|
||||
"""
|
||||
warnings.warn('get_year_sixty_cycle() is deprecated, please use SixtyCycleHour.get_day() instead.', DeprecationWarning)
|
||||
return self.get_sixty_cycle_hour().get_day()
|
||||
|
||||
def get_sixty_cycle(self) -> SixtyCycle:
|
||||
"""
|
||||
时辰干支
|
||||
:return: 干支 SixtyCycle
|
||||
"""
|
||||
from tyme4py.sixtycycle import SixtyCycle, HeavenStem
|
||||
e: int = self.get_index_in_day()
|
||||
h: HeavenStem = self.get_lunar_day().get_sixty_cycle().get_heaven_stem()
|
||||
if self._hour >= 23:
|
||||
h = h.next(1)
|
||||
e = 0
|
||||
return SixtyCycle.from_index(h.get_index() * 12 + e)
|
||||
|
||||
def get_twelve_star(self) -> TwelveStar:
|
||||
"""
|
||||
:return: 黄道黑道十二神 TwelveStar
|
||||
"""
|
||||
return TwelveStar(self.get_sixty_cycle().get_earth_branch().get_index() + (8 - self.get_sixty_cycle_hour().get_day().get_earth_branch().get_index() % 6) * 2)
|
||||
|
||||
def get_nine_star(self) -> NineStar:
|
||||
"""
|
||||
九星(时家紫白星歌诀:三元时白最为佳,冬至阳生顺莫差,孟日七宫仲一白,季日四绿发萌芽,每把时辰起甲子,本时星耀照光华,时星移入中宫去,顺飞八方逐细查。夏至阴生逆回首,孟归三碧季加六,仲在九宫时起甲,依然掌中逆轮跨。)
|
||||
:return: 九星 NineStar
|
||||
"""
|
||||
from tyme4py.solar import SolarTerm
|
||||
d: LunarDay = self.get_lunar_day()
|
||||
solar: SolarDay = d.get_solar_day()
|
||||
dong_zhi: SolarTerm = SolarTerm(solar.get_year(), 0)
|
||||
earth_branch_index: int = self.get_index_in_day() % 12
|
||||
index: int = 8 - 3 * (d.get_sixty_cycle().get_earth_branch().get_index() % 3)
|
||||
if (not solar.is_before(dong_zhi.get_julian_day().get_solar_day())) and solar.is_before(dong_zhi.next(12).get_julian_day().get_solar_day()):
|
||||
index = 8 + earth_branch_index - index
|
||||
else:
|
||||
index -= earth_branch_index
|
||||
return NineStar(index)
|
||||
|
||||
def get_solar_time(self) -> SolarTime:
|
||||
"""
|
||||
公历时刻
|
||||
:return: 公历时刻 SolarTime
|
||||
"""
|
||||
from tyme4py.solar import SolarTime
|
||||
d: SolarDay = self.get_lunar_day().get_solar_day()
|
||||
return SolarTime(d.get_year(), d.get_month(), d.get_day(), self._hour, self._minute, self._second)
|
||||
|
||||
def get_sixty_cycle_hour(self) -> SixtyCycleHour:
|
||||
"""
|
||||
干支时辰
|
||||
:return: 干支时辰 SixtyCycleHour
|
||||
"""
|
||||
return self.get_solar_time().get_sixty_cycle_hour()
|
||||
|
||||
def get_eight_char(self) -> EightChar:
|
||||
"""
|
||||
八字
|
||||
:return: 八字
|
||||
"""
|
||||
return LunarHour.provider.get_eight_char(self)
|
||||
|
||||
def get_recommends(self) -> List[Taboo]:
|
||||
"""
|
||||
宜
|
||||
:return: 宜忌列表
|
||||
"""
|
||||
return Taboo.get_hour_recommends(self.get_sixty_cycle_hour().get_day(), self.get_sixty_cycle())
|
||||
|
||||
def get_avoids(self) -> List[Taboo]:
|
||||
"""
|
||||
忌
|
||||
:return: 宜忌列表
|
||||
"""
|
||||
return Taboo.get_hour_avoids(self.get_sixty_cycle_hour().get_day(), self.get_sixty_cycle())
|
||||
|
||||
def get_minor_ren(self) -> MinorRen:
|
||||
"""
|
||||
:return: 小六壬
|
||||
"""
|
||||
return self.get_lunar_day().get_minor_ren().next(self.get_index_in_day())
|
||||
Vendored
+408
@@ -0,0 +1,408 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING, Union, List, Dict
|
||||
|
||||
from tyme4py import AbstractTyme
|
||||
from tyme4py.culture import Element, Zodiac
|
||||
from tyme4py.lunar import LunarMonth
|
||||
from tyme4py.unit import MonthUnit, DayUnit
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from tyme4py.sixtycycle import SixtyCycle
|
||||
from tyme4py.solar import SolarYear, SolarDay
|
||||
|
||||
|
||||
class RabByungElement(Element):
|
||||
"""藏历五行"""
|
||||
|
||||
NAMES: List[str] = ['木', '火', '土', '铁', '水']
|
||||
"""名称"""
|
||||
|
||||
def __init__(self, index_or_name: Union[int, str]):
|
||||
super().__init__(index_or_name, self.NAMES)
|
||||
|
||||
@classmethod
|
||||
def from_index(cls, index: int) -> RabByungElement:
|
||||
return cls(index)
|
||||
|
||||
@classmethod
|
||||
def from_name(cls, name: str) -> RabByungElement:
|
||||
return cls(name)
|
||||
|
||||
def next(self, n: int) -> RabByungElement:
|
||||
return RabByungElement(self.next_index(n))
|
||||
|
||||
def get_reinforce(self) -> RabByungElement:
|
||||
"""我生者"""
|
||||
return self.next(1)
|
||||
|
||||
def get_restrain(self) -> RabByungElement:
|
||||
"""我克者"""
|
||||
return self.next(2)
|
||||
|
||||
def get_reinforced(self) -> RabByungElement:
|
||||
"""生我者"""
|
||||
return self.next(-1)
|
||||
|
||||
def get_restrained(self) -> RabByungElement:
|
||||
"""克我者"""
|
||||
return self.next(-2)
|
||||
|
||||
|
||||
class RabByungYear(AbstractTyme):
|
||||
"""藏历年(公历1027年为藏历元年,第一饶迥火兔年)"""
|
||||
|
||||
def __init__(self, rab_byung_index: int, element_index: int, zodiac_index: int):
|
||||
"""
|
||||
:param rab_byung_index: 饶迥(胜生周)序号,从0开始
|
||||
:param element_index: 五行索引,从0开始
|
||||
:param zodiac_index: 生肖索引,从0开始
|
||||
"""
|
||||
if rab_byung_index < 0 or rab_byung_index > 150:
|
||||
raise ValueError(f'illegal rab-byung index: {rab_byung_index}')
|
||||
if element_index < 0 or element_index >= len(Element.NAMES):
|
||||
raise ValueError(f'illegal element index: {element_index}')
|
||||
if zodiac_index < 0 or zodiac_index > len(Zodiac.NAMES):
|
||||
raise ValueError(f'illegal zodiac index: {zodiac_index}')
|
||||
self._rab_byung_index = rab_byung_index
|
||||
self._element_index = element_index
|
||||
self._zodiac_index = zodiac_index
|
||||
|
||||
@staticmethod
|
||||
def validate(year: int) -> None:
|
||||
if year < 1027 or year > 9999:
|
||||
raise ValueError(f'illegal rab-byung year: {year}')
|
||||
|
||||
@classmethod
|
||||
def from_sixty_cycle(cls, rab_byung_index: int, sixty_cycle: SixtyCycle) -> RabByungYear:
|
||||
return cls(rab_byung_index, sixty_cycle.get_heaven_stem().get_element().get_index(), sixty_cycle.get_earth_branch().get_zodiac().get_index())
|
||||
|
||||
@classmethod
|
||||
def from_element_zodiac(cls, rab_byung_index: int, element: RabByungElement, zodiac: Zodiac) -> RabByungYear:
|
||||
return cls(rab_byung_index, element.get_index(), zodiac.get_index())
|
||||
|
||||
@classmethod
|
||||
def from_year(cls, year: int) -> RabByungYear:
|
||||
from tyme4py.sixtycycle import SixtyCycle
|
||||
cls.validate(year)
|
||||
return cls.from_sixty_cycle((year - 1024) // 60, SixtyCycle.from_index(year - 4))
|
||||
|
||||
def get_rab_byung_index(self) -> int:
|
||||
"""饶迥序号(从0开始)"""
|
||||
return self._rab_byung_index
|
||||
|
||||
def get_sixty_cycle(self) -> SixtyCycle:
|
||||
"""干支"""
|
||||
from tyme4py.sixtycycle import SixtyCycle
|
||||
return SixtyCycle.from_index(6 * (self._element_index * 2 + self._zodiac_index % 2) - 5 * self._zodiac_index)
|
||||
|
||||
def get_zodiac(self) -> Zodiac:
|
||||
"""生肖"""
|
||||
return Zodiac.from_index(self._zodiac_index)
|
||||
|
||||
def get_element(self) -> RabByungElement:
|
||||
"""五行"""
|
||||
return RabByungElement.from_index(self._element_index)
|
||||
|
||||
def get_name(self) -> str:
|
||||
"""完整名称"""
|
||||
digits: List[str] = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九']
|
||||
units: List[str] = ['', '十', '百']
|
||||
n: int = self._rab_byung_index + 1
|
||||
s: str = ''
|
||||
pos: int = 0
|
||||
|
||||
while n > 0:
|
||||
digit: int = n % 10
|
||||
if digit > 0:
|
||||
s = digits[digit] + units[pos] + s
|
||||
elif s:
|
||||
s = digits[digit] + s
|
||||
n //= 10
|
||||
pos += 1
|
||||
|
||||
if s.startswith('一十'):
|
||||
s = s.replace('一十', '十', 1)
|
||||
return f'第{s}饶迥{self.get_element()}{self.get_zodiac()}年'
|
||||
|
||||
def next(self, n: int) -> RabByungYear:
|
||||
return RabByungYear.from_year(self.get_year() + n)
|
||||
|
||||
def get_year(self) -> int:
|
||||
"""公历年份"""
|
||||
return 1024 + self._rab_byung_index * 60 + self.get_sixty_cycle().get_index()
|
||||
|
||||
def get_leap_month(self) -> int:
|
||||
"""闰月(闰月数字,1代表闰1月,0代表无闰月)"""
|
||||
y: int = 1
|
||||
m: int = 4
|
||||
t: int = 1
|
||||
current_year: int = self.get_year()
|
||||
|
||||
while y < current_year:
|
||||
i: int = m + 31 + t
|
||||
y += 2
|
||||
m = i - 23
|
||||
if i > 35:
|
||||
y += 1
|
||||
m -= 12
|
||||
t = 1 - t
|
||||
|
||||
return m if y == current_year else 0
|
||||
|
||||
def get_solar_year(self) -> SolarYear:
|
||||
"""对应的公历年"""
|
||||
from tyme4py.solar import SolarYear
|
||||
return SolarYear.from_year(self.get_year())
|
||||
|
||||
def get_first_month(self) -> RabByungMonth:
|
||||
"""首月"""
|
||||
return RabByungMonth(self.get_year(), 1)
|
||||
|
||||
def get_month_count(self) -> int:
|
||||
"""月份数量"""
|
||||
return 12 if self.get_leap_month() < 1 else 13
|
||||
|
||||
def get_months(self) -> List[RabByungMonth]:
|
||||
"""所有月份列表"""
|
||||
months: List[RabByungMonth] = []
|
||||
y: int = self.get_year()
|
||||
leap_month: int = self.get_leap_month()
|
||||
for i in range(1, 13):
|
||||
months.append(RabByungMonth(y, i))
|
||||
if i == leap_month:
|
||||
months.append(RabByungMonth(y, -i))
|
||||
return months
|
||||
|
||||
def __str__(self) -> str:
|
||||
return self.get_name()
|
||||
|
||||
|
||||
class RabByungMonth(MonthUnit):
|
||||
"""藏历月,仅支持藏历1950年十二月至藏历2050年十二月"""
|
||||
ALIAS = ['神变月', '苦行月', '具香月', '萨嘎月', '作净月', '明净月', '具醉月', '具贤月', '天降月', '持众月', '庄严月', '满意月']
|
||||
DAYS: Dict[int, List[int]] = {}
|
||||
_IS_INIT: bool = False
|
||||
|
||||
# 初始化特殊日数据(1950-2050年)
|
||||
@staticmethod
|
||||
def _init():
|
||||
if RabByungMonth._IS_INIT:
|
||||
return
|
||||
|
||||
years: List[str] = "2c>,182[>1:2TA4ZI=n1E2Bk1J2Ff3Mk503Oc62g=,172^>1:2XA1>2UE2Bo1I2Fj3Lo62Fb3Mf5,03N^72b=1:2]A1>2ZF1B2VI2Em1K2Fe,2Lh1R3Na603P\\:172Y>1;2UB2=m2Dq1J2Eh,2Kl1Q3Me603Pa:172^>1;2YA2=p1C2UI,2Dk2Jp3QEc3Mi603Pf:3L[72b?1:2]A1<2UB2XH,2Cn1I2Ei1L2Ie1Q3Na703Q\\:2`@1;2XA,4\\H;m1B2TI2Em1L2Ij1Q3Nf603Q`903QW:,2[@1;2TB2XI1E4TMAh2Io3RFe3Mj603Pc803Q[;,2^?1;2WA2>q1E2Bm1I2Fi1M2Hc3Of70,3P^82a>1:2[A1>2WE1B2TI2Fm1L2Hf3Ni6,03Oa703PZ:3`A62V>4]F;q1B4YJ>l2Eq1L2Gi3Ml5,03Nd603Q_9172[>1;2XB2>p1E2VK2Fl,1K2Fc3Mh603Pc9172`>1;2\\B1>2UD2=j2En,1J2Fg3Mm62Ib3Pj;3M_703R[:2`B1=2YB2=n,1C2TI2Fk1L2Ig1P3Nd703Q_:152X<2[A,2<q1B2WI2Ep1L2Il1Q3Ni703Qc9152[:2^@,1;2WB2>o1E2Bk1I2Fh1M2Ib3Pf803R^9,2a?1;2ZA1>2UE2Bp1I2Fl1M2If3Oi80,3Pa803QY:2^A1>2ZE1B4WJ>j2Fp1M2Hi1N2H`,3Od703Q]:162Y>1;2VB2?o1E4VM@h2Gl1M,2Hd3Ng603Qa9172^>1;2ZB1?2UE2@l2Fo1L,2Gg3Mk62H`3Pf:172c?3QY;2_B1>2YD2?o1E,2TK2Fj1M2Ie1P3Mb703R^;172X=2\\C1>,2TD2WJ2Fn1L2Ij1P3Ng703Rb:162[<2_B1=,2VC2>m1E4TMAh2Io3QFe3Nl82Ja3Qf:152_;0,3RU<2ZB1>2TE2Bn1I2Fj1M2Je3Pk:2K^3Ra:,03RY;2]A1>2XE1B2TI2Fo1M2Ii1P2Ka3Qd8,03R]:3bB62W>4]F:q1B2?n1F4VNAh2Il1O2Jd,3Pg803Q`:162\\=1;2XB1?2TF2Bl2Ho1N,2Ig3Nk703Qd9162`>1;2]B1?2XE2Ao1G2TM,2Hj1M2Id1P3M_603R\\;172W>2\\E1@2TE,2?i2Gm1M2Ih1P3Md603Ra;172[=28q1?2WD,2?m2Fq1M2Il1P3Mi72I^3Re:162_<172W=,2ZC2?q1E2Bk1I2Fh1M2Jd1Q3M^52b;16,2Y<2]B1>2VE2Bp1I2Fm1M2Jh1Q2Lb3Re:15,2\\;3aC62U>2[E1B4WJ>k1F4TNBg2Jl1P2Le3Qh9,03R`:172Z=1:2VB2?q1F2Bk2Ip1P2Jg,1P2J_3Qc:162^=1;2[B1?2WF2Bo1H2Bg2Ij,1O2Jc3Qg:3L\\62c>3QY;3aC72V?2[F1A2TG2Bj,2Hm1N2Jg1P3Mb603R_;182Z>1:2T@2WF2Am,2Gp1M2Ik1P3Mg603Rc;172^>192W?2ZE,2@p1F2Bj2Io3QEe1M2Jb1Q3M]72b=182Z>,2]D1?2VE2Bn1I2Fk1M2Jg1Q3Ma62e<172]=,172U>2YE1B2UI2Fp1N2Jk1Q3Me503M\\6,2`<172Y>3_F:2TB2?n1F2Cj2Jo3QDc2Lh1R,3L_52c;172]=1:2XB1?2UF2Cn1I2Eg2Kk1P,2Lb3Rf;162a=1:2]B1?2ZF1B2TH2Dj2Jm,1O2Kf1Q3M`603Q\\;182Y?2;q1A2WH2Cm,2Hq1O2Ji1P3Me603Qa;182]>1:2WA2[G2Ap,1G2Bi2Im1P3Mi72I_3Qf;3N\\72Eh1:2Z?29o,1@2UF2Bm1I2Fh1M2Je1Q3N`72f?3PY92]>19,2U?2YF2Bq1I2Fm1M2Jj1Q3Nd603O]72`=,182X?4]F:o1B4WI=k1F4UNCi2Jn3REc3Mh503N`6,2c<182\\>1:2VA2?q1F2Cm1J2Fg2Lk1R3Mc5,2f<172`=1:2[A1?2XF2Cq1I2Ek2Kn1R,2Lf1R3N_62d>3PZ:3aC72W?2;p1B2WI2Dn1J,2De2Ki1Q3Mc603Q_:182\\?1;2VB2<m2Cq1I,2Dh2Jl1P3Mg603Qd;182`?1;2ZA2<p1B,2UH2Cl1I2Ef3Mm82Jc1Q3N_703QY:2]@1;2UA,2XG2Bp1I2Fk1M2Jh1Q3Nc703Q]92`?1:,2X@4\\G:n1B2VI2Fp1M2Jl1R3Ng603P`82d>,192[?1;2UA2>o1F2Ck1J2Gg3Mk603Oc70,3OZ82_>1:2YA1?2VF2Cp1J2Fj1M2Gc3Nf5,03O^72b>1:2^B1?4[G;n1C2VJ2Fn1L2Gf,3Mi503Nb603Q]:172Y?1<2UB2>m2Eq1K2Fi,2Kl1R3Mf603Qa:182^?1;2YB2>q1D2VJ,2Dl1J2Fe3Mj603Qg;3N]72c@3QX;2]A1=2VB,2YI2Co1J2Fi1M2Je1Q3Nb703R]:2aA1<2XA,2<n1C2UI2Fn1M2Jj1Q3Nf703Q`903RX:,2[@1<2TB4YJ>l1E4UNBi1J2Ge3Mk703Pc803Q[9,2^?1;2XB2>q1E2Cn1J2Gj1M2Ic3Of70,3P^82b?1;2\\A1>2XF1C2UJ2Fm1M2Hf3Ni6,03Oa703Q[:3aB72W>1<2TC2?m2Fq1L2Gi3Ml5,03Ne703Q_:172\\>1<2XB2?q1E2WL2Fl,1L2Gd3Ni603Qd:172a?1;2\\B1>2VD2>k,2Eo1K2Gh1M2Ic1Q3N`703R\\;3aC62U=2YC2>o,1D2TJ2Fl1M2Jh1Q3Ne703R`:162Y<2\\B,1=2TC4XJ=j2Fp1M2Jm3QFc3Ni803Qc:152\\;2_A,1<2WB2>o1E2Bl1J2Gh1N2Jc3Qg903R^:,2b@1;2[B1>2VE2Cq1J2Gl1N2Jf3Pj80,3Qa803RZ;2_B1>4[F:o1C4XK?k2Fp1M2Ii1O2Ia,3Pd703R^:172Y>1<2VC2?p1F2Ai2Hl1M,2Hd3Oh703Qb:172^>1<2[C1?2UE2Al2Go,1L2Hg3Nl82Ia3Qg;3M]72e@3RZ;3`C72T>2YD2@o1E,2TK2Gk1M2Jf1Q3Nb703R^;172Y=2\\D1>,2TD4XK>i2Fo1M2Jj1Q3Ng703Rb;172\\<2`C1=,2WC2?n1F4VNBi1J2Gf1N2Kb3Rf:162_;15,2V<2ZB1?2TE2Bn1J2Gk1N2Kf1Q2L^3Rb:,152Z;2^B1>2YE1B2UJ2Go1N2Ji1P2Kb3Qd9,03R];172X>1;2TC2@n1G2Bi2Im1O2Jd,3Ph803Ra:172\\>1;2YC1@2UF2Bl2Hp1N,2Ig3Ol82J`3Qe:172a>1;4^C7q1?2XF2Ao1G2UN,2Hj1N2Jd1Q3N`703R];182X>2]F1@2TF,2@j2Gn1M2Jq1Q3Ne703Ra;172\\>192T?,2WE2@m1F4TMAf2Im3QEc3Nj82J`3Rf;172_=182W>,2ZD2?q1F2Bl1I2Gj1N2Ke1R3M_62b<17,2Z=2]C1?2WE2Bq1I2Gn1N2Ki1Q3Mb52e;16,2]<172V>4[F:o1B4XK?l1G4UOCh2Jl1Q2Le3Rh:,152`;172Z>1;2WB2@q1G2Cl2Ip1P2K_".split(',')
|
||||
|
||||
y: int = 1950
|
||||
m: int = 11
|
||||
for ys in years:
|
||||
data: str = ys.strip()
|
||||
while data:
|
||||
length: int = ord(data[0]) - 48
|
||||
chunk: str = data[1:1+length]
|
||||
data: str = data[1+length:]
|
||||
days_data: List[int] = [ord(c) - 53 - 30 for c in chunk]
|
||||
RabByungMonth.DAYS[y * 13 + m] = days_data
|
||||
m += 1
|
||||
y += 1
|
||||
m = 0
|
||||
RabByungMonth._IS_INIT = True
|
||||
|
||||
def __init__(self, year: int, month: int):
|
||||
RabByungMonth._init()
|
||||
RabByungMonth.validate(year, month)
|
||||
super().__init__(year, abs(month))
|
||||
self._leap = month < 0
|
||||
|
||||
@staticmethod
|
||||
def validate(year: int, month: int) -> None:
|
||||
if month == 0 or month > 12 or month < -12:
|
||||
raise ValueError(f'illegal rab-byung month: {month}')
|
||||
if year < 1950 or year > 2050:
|
||||
raise ValueError(f'rab-byung year {year} must between 1950 and 2050')
|
||||
leap: bool = month < 0
|
||||
m: int = abs(month)
|
||||
if year == 1950 and m < 12:
|
||||
raise ValueError(f'month {month} must be 12 in rab-byung year {year}')
|
||||
if leap and m != RabByungYear.from_year(year).get_leap_month():
|
||||
raise ValueError(f'illegal leap month {m} in rab-byung year {year}')
|
||||
|
||||
@classmethod
|
||||
def from_ym(cls, year: int, month: int) -> RabByungMonth:
|
||||
return cls(year, month)
|
||||
|
||||
def get_rab_byung_year(self) -> RabByungYear:
|
||||
return RabByungYear.from_year(self._year)
|
||||
|
||||
def get_month_with_leap(self) -> int:
|
||||
return -self._month if self._leap else self._month
|
||||
|
||||
def get_index_in_year(self) -> int:
|
||||
index: int = self._month - 1
|
||||
if self._leap:
|
||||
index += 1
|
||||
else:
|
||||
leap_month: int = self.get_rab_byung_year().get_leap_month()
|
||||
if 0 < leap_month < self._month:
|
||||
index += 1
|
||||
return index
|
||||
|
||||
def is_leap(self) -> bool:
|
||||
return self._leap
|
||||
|
||||
def get_name(self) -> str:
|
||||
return ('闰' if self._leap else '') + LunarMonth.NAMES[self._month - 1]
|
||||
|
||||
def get_alias(self) -> str:
|
||||
return ('闰' if self._leap else '') + self.ALIAS[self._month - 1]
|
||||
|
||||
def next(self, n: int) -> RabByungMonth:
|
||||
if n == 0:
|
||||
return RabByungMonth.from_ym(self.get_year(), self.get_month_with_leap())
|
||||
m: int = self.get_index_in_year() + 1 + n
|
||||
y: RabByungYear = self.get_rab_byung_year()
|
||||
if n > 0:
|
||||
month_count: int = y.get_month_count()
|
||||
while m > month_count:
|
||||
m -= month_count
|
||||
y = y.next(1)
|
||||
month_count = y.get_month_count()
|
||||
else:
|
||||
while m <= 0:
|
||||
y = y.next(-1)
|
||||
m += y.get_month_count()
|
||||
|
||||
leap: bool = False
|
||||
leap_month: int = y.get_leap_month()
|
||||
if leap_month > 0:
|
||||
if m == leap_month + 1:
|
||||
leap = True
|
||||
if m > leap_month:
|
||||
m -= 1
|
||||
return RabByungMonth(y.get_year(), -m if leap else m)
|
||||
|
||||
def get_first_day(self) -> RabByungDay:
|
||||
return RabByungDay(self._year, self.get_month_with_leap(), 1)
|
||||
|
||||
def get_days(self) -> List[RabByungDay]:
|
||||
days: List[RabByungDay] = []
|
||||
miss_days: List[int] = self.get_miss_days()
|
||||
leap_days: List[int] = self.get_leap_days()
|
||||
m: int = self.get_month_with_leap()
|
||||
for day in range(1, 31):
|
||||
if day in miss_days:
|
||||
continue
|
||||
days.append(RabByungDay(self._year, m, day))
|
||||
if day in leap_days:
|
||||
days.append(RabByungDay(self._year, m, -day))
|
||||
return days
|
||||
|
||||
def get_day_count(self) -> int:
|
||||
return 30 + len(self.get_leap_days()) - len(self.get_miss_days())
|
||||
|
||||
def get_special_days(self) -> List[int]:
|
||||
return self.DAYS.get(self.get_year() * 13 + self.get_index_in_year(), [])
|
||||
|
||||
def get_leap_days(self) -> List[int]:
|
||||
return [d for d in self.get_special_days() if d > 0]
|
||||
|
||||
def get_miss_days(self) -> List[int]:
|
||||
return [-d for d in self.get_special_days() if d < 0]
|
||||
|
||||
def __str__(self) -> str:
|
||||
return f'{self.get_rab_byung_year()}{self.get_name()}'
|
||||
|
||||
|
||||
class RabByungDay(DayUnit):
|
||||
"""藏历日,仅支持藏历1950年十二月初一(公历1951年1月8日)至藏历2050年十二月三十(公历2051年2月11日)"""
|
||||
NAMES: List[str] = ['初一', '初二', '初三', '初四', '初五', '初六', '初七', '初八', '初九', '初十', '十一', '十二', '十三', '十四', '十五', '十六', '十七', '十八', '十九', '二十', '廿一', '廿二', '廿三', '廿四', '廿五', '廿六', '廿七', '廿八', '廿九', '三十']
|
||||
|
||||
def __init__(self, year: int, month: int, day: int):
|
||||
RabByungDay.validate(year, month, day)
|
||||
super().__init__(year, month, abs(day))
|
||||
self._leap = day < 0
|
||||
|
||||
@staticmethod
|
||||
def validate(year: int, month: int, day: int) -> None:
|
||||
if day == 0 or day < -30 or day > 30:
|
||||
raise ValueError(f'illegal day {day} in {month}')
|
||||
m: RabByungMonth = RabByungMonth.from_ym(year, month)
|
||||
leap: bool = day < 0
|
||||
d = abs(day)
|
||||
if leap and d not in m.get_leap_days():
|
||||
raise ValueError(f'illegal leap day {d} in {m}')
|
||||
if not leap and d in m.get_miss_days():
|
||||
raise ValueError(f'illegal day {d} in {m}')
|
||||
|
||||
@classmethod
|
||||
def from_ymd(cls, year: int, month: int, day: int) -> RabByungDay:
|
||||
return cls(year, month, day)
|
||||
|
||||
@classmethod
|
||||
def from_solar_day(cls, solar_day: SolarDay) -> RabByungDay:
|
||||
from tyme4py.solar import SolarDay
|
||||
days: int = solar_day.subtract(SolarDay.from_ymd(1951, 1, 8))
|
||||
m: RabByungMonth = RabByungMonth.from_ym(1950, 12)
|
||||
count: int = m.get_day_count()
|
||||
while days >= count:
|
||||
days -= count
|
||||
m = m.next(1)
|
||||
count = m.get_day_count()
|
||||
day: int = days + 1
|
||||
for d in m.get_special_days():
|
||||
if d < 0:
|
||||
if day >= -d:
|
||||
day += 1
|
||||
elif d > 0:
|
||||
if day == d + 1:
|
||||
day = -d
|
||||
break
|
||||
elif day > d + 1:
|
||||
day -= 1
|
||||
return RabByungDay(m.get_year(), m.get_month_with_leap(), day)
|
||||
|
||||
def get_rab_byung_month(self) -> RabByungMonth:
|
||||
return RabByungMonth.from_ym(self._year, self._month)
|
||||
|
||||
def is_leap(self) -> bool:
|
||||
return self._leap
|
||||
|
||||
def get_day_with_leap(self) -> int:
|
||||
return -self._day if self._leap else self._day
|
||||
|
||||
def get_name(self) -> str:
|
||||
return ('闰' if self._leap else '') + self.NAMES[self._day - 1]
|
||||
|
||||
def subtract(self, target: RabByungDay) -> int:
|
||||
return self.get_solar_day().subtract(target.get_solar_day())
|
||||
|
||||
def get_solar_day(self) -> SolarDay:
|
||||
from tyme4py.solar import SolarDay
|
||||
month: RabByungMonth = RabByungMonth.from_ym(1950, 12)
|
||||
cm: RabByungMonth = self.get_rab_byung_month()
|
||||
total_days: int = 0
|
||||
|
||||
# 计算从1950年12月到当前月的总天数
|
||||
while month != cm:
|
||||
total_days += month.get_day_count()
|
||||
month = month.next(1)
|
||||
|
||||
day_num: int = self._day
|
||||
for d in month.get_special_days():
|
||||
if d < 0:
|
||||
if day_num > -d:
|
||||
day_num -= 1
|
||||
elif d > 0:
|
||||
if day_num > d:
|
||||
day_num += 1
|
||||
|
||||
if self._leap:
|
||||
day_num += 1
|
||||
|
||||
return SolarDay.from_ymd(1951, 1, 7).next(total_days + day_num)
|
||||
|
||||
def next(self, n: int) -> RabByungDay:
|
||||
return self.get_solar_day().next(n).get_rab_byung_day()
|
||||
|
||||
def __str__(self) -> str:
|
||||
return f'{self.get_rab_byung_month()}{self.get_name()}'
|
||||
+919
@@ -0,0 +1,919 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
from __future__ import annotations
|
||||
|
||||
from math import floor, ceil
|
||||
from typing import TYPE_CHECKING, Union, List
|
||||
|
||||
from tyme4py import LoopTyme, AbstractCulture, AbstractCultureDay, AbstractTyme
|
||||
from tyme4py.culture import Element, Direction, Zodiac, Terrain, Sound, Ten, Twenty, Duty, God, Taboo
|
||||
from tyme4py.culture.fetus import FetusDay
|
||||
from tyme4py.culture.pengzu import PengZuEarthBranch, PengZuHeavenStem, PengZu
|
||||
from tyme4py.culture.star.nine import NineStar
|
||||
from tyme4py.culture.star.ten import TenStar
|
||||
from tyme4py.culture.star.twelve import TwelveStar
|
||||
from tyme4py.eightchar import EightChar
|
||||
from tyme4py.enums import YinYang, HideHeavenStemType
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from tyme4py.solar import SolarDay, SolarTime
|
||||
from tyme4py.culture.star.twentyeight import TwentyEightStar
|
||||
|
||||
|
||||
class ThreePillars(AbstractCulture):
|
||||
"""三柱"""
|
||||
|
||||
def __init__(self, year: Union[SixtyCycle, str], month: Union[SixtyCycle, str], day: Union[SixtyCycle, str]):
|
||||
"""
|
||||
:param year: 年干支
|
||||
:param month: 月干支
|
||||
:param day: 日干支
|
||||
"""
|
||||
self._year = year if isinstance(year, SixtyCycle) else SixtyCycle(year)
|
||||
self._month = month if isinstance(month, SixtyCycle) else SixtyCycle(month)
|
||||
self._day = day if isinstance(day, SixtyCycle) else SixtyCycle(day)
|
||||
|
||||
def get_year(self) -> SixtyCycle:
|
||||
"""
|
||||
年柱
|
||||
:return: 干支 SixtyCycle
|
||||
"""
|
||||
return self._year
|
||||
|
||||
def get_month(self) -> SixtyCycle:
|
||||
"""
|
||||
月柱
|
||||
:return: 干支 SixtyCycle
|
||||
"""
|
||||
return self._month
|
||||
|
||||
def get_day(self) -> SixtyCycle:
|
||||
"""
|
||||
日柱
|
||||
:return: 干支 SixtyCycle
|
||||
"""
|
||||
return self._day
|
||||
|
||||
def get_name(self) -> str:
|
||||
return f'{self._year} {self._month} {self._day}'
|
||||
|
||||
def get_solar_days(self, start_year: int, end_year: int) -> List[SolarDay]:
|
||||
"""
|
||||
三柱转公历日列表
|
||||
:param start_year: 开始年份,支持1-9999年
|
||||
:param end_year: 结束年份,支持1-9999年
|
||||
:return: 公历日 SolarDay的列表
|
||||
"""
|
||||
from tyme4py.solar import SolarDay, SolarTerm
|
||||
l: List[SolarDay] = []
|
||||
# 月地支距寅月的偏移值
|
||||
m: int = self._month.get_earth_branch().next(-2).get_index()
|
||||
# 月天干要一致
|
||||
if not HeavenStem((self._year.get_heaven_stem().get_index() + 1) * 2 + m) == self._month.get_heaven_stem():
|
||||
return l
|
||||
|
||||
# 1年的立春是辛酉,序号57
|
||||
y: int = self._year.next(-57).get_index() + 1
|
||||
# 节令偏移值
|
||||
m *= 2
|
||||
base_year: int = start_year - 1
|
||||
if base_year > y:
|
||||
y += 60 * int(ceil((base_year - y) / 60.0))
|
||||
|
||||
while y <= end_year:
|
||||
# 立春为寅月的开始
|
||||
term: SolarTerm = SolarTerm(y, 3)
|
||||
# 节令推移,年干支和月干支就都匹配上了
|
||||
if m > 0:
|
||||
term = term.next(m)
|
||||
|
||||
solar_day: SolarDay = term.get_solar_day()
|
||||
if solar_day.get_year() >= start_year:
|
||||
# 日干支和节令干支的偏移值
|
||||
d: int = self._day.next(-solar_day.get_lunar_day().get_sixty_cycle().get_index()).get_index()
|
||||
if d > 0:
|
||||
# 从节令推移天数
|
||||
solar_day = solar_day.next(d)
|
||||
|
||||
# 验证一下
|
||||
if solar_day.get_sixty_cycle_day().get_three_pillars() == self:
|
||||
l.append(solar_day)
|
||||
y += 60
|
||||
return l
|
||||
|
||||
|
||||
class EarthBranch(LoopTyme):
|
||||
"""地支(地元)"""
|
||||
NAMES: List[str] = ['子', '丑', '寅', '卯', '辰', '巳', '午', '未', '申', '酉', '戌', '亥']
|
||||
"""名称"""
|
||||
|
||||
def __init__(self, index_or_name: Union[int, str]):
|
||||
super().__init__(self.NAMES, index_or_name)
|
||||
|
||||
@classmethod
|
||||
def from_name(cls, name: str) -> EarthBranch:
|
||||
return cls(name)
|
||||
|
||||
@classmethod
|
||||
def from_index(cls, index: int) -> EarthBranch:
|
||||
return cls(index)
|
||||
|
||||
def next(self, n: int) -> EarthBranch:
|
||||
return EarthBranch(self.next_index(n))
|
||||
|
||||
def get_element(self) -> Element:
|
||||
"""
|
||||
:return:五行
|
||||
"""
|
||||
return Element([4, 2, 0, 0, 2, 1, 1, 2, 3, 3, 2, 4][self.get_index()])
|
||||
|
||||
def get_yin_yang(self) -> YinYang:
|
||||
"""
|
||||
:return:阴阳
|
||||
"""
|
||||
return YinYang.YANG if self.get_index() % 2 == 0 else YinYang.YIN
|
||||
|
||||
def get_hide_heaven_stem_main(self) -> HeavenStem:
|
||||
"""
|
||||
藏干之本气(主气)
|
||||
:return: 天干 HeavenStem
|
||||
"""
|
||||
return HeavenStem([9, 5, 0, 1, 4, 2, 3, 5, 6, 7, 4, 8][self.get_index()])
|
||||
|
||||
def get_hide_heaven_stem_middle(self) -> Union[HeavenStem, None]:
|
||||
"""
|
||||
藏干之中气,无中气的返回None
|
||||
:return: 天干 HeavenStem
|
||||
"""
|
||||
n: int = [-1, 9, 2, -1, 1, 6, 5, 3, 8, -1, 7, 0][self.get_index()]
|
||||
return None if n == -1 else HeavenStem(n)
|
||||
|
||||
def get_hide_heaven_stem_residual(self) -> Union[HeavenStem, None]:
|
||||
"""
|
||||
藏干之余气,无余气的返回None
|
||||
:return: 天干 HeavenStem
|
||||
"""
|
||||
n: int = [-1, 7, 4, -1, 9, 4, -1, 1, 4, -1, 3, -1][self.get_index()]
|
||||
return None if n == -1 else HeavenStem(n)
|
||||
|
||||
def get_hide_heaven_stems(self) -> List[HideHeavenStem]:
|
||||
"""
|
||||
:return: 藏干列表
|
||||
"""
|
||||
l: List[HideHeavenStem] = [HideHeavenStem(self.get_hide_heaven_stem_main(), HideHeavenStemType.MAIN)]
|
||||
o: Union[HeavenStem, None] = self.get_hide_heaven_stem_middle()
|
||||
if o:
|
||||
l.append(HideHeavenStem(o, HideHeavenStemType.MIDDLE))
|
||||
o = self.get_hide_heaven_stem_residual()
|
||||
if o:
|
||||
l.append(HideHeavenStem(o, HideHeavenStemType.RESIDUAL))
|
||||
return l
|
||||
|
||||
def get_zodiac(self) -> Zodiac:
|
||||
"""
|
||||
生肖属相
|
||||
:return:生肖 Zodiac
|
||||
"""
|
||||
return Zodiac(self.get_index())
|
||||
|
||||
def get_direction(self) -> Direction:
|
||||
"""
|
||||
:return: 方位 Direction
|
||||
"""
|
||||
return Direction([0, 4, 2, 2, 4, 8, 8, 4, 6, 6, 4, 0][self.get_index()])
|
||||
|
||||
def get_opposite(self) -> EarthBranch:
|
||||
"""
|
||||
六冲
|
||||
子午冲,丑未冲,寅申冲,辰戌冲,卯酉冲,巳亥冲。
|
||||
:return: 地支 EarthBranch
|
||||
"""
|
||||
return self.next(6)
|
||||
|
||||
def get_ominous(self) -> Direction:
|
||||
"""
|
||||
煞
|
||||
逢巳日、酉日、丑日必煞东;
|
||||
亥日、卯日、未日必煞西;
|
||||
申日、子日、辰日必煞南;
|
||||
寅日、午日、戌日必煞北。
|
||||
:return: 方位 Direction
|
||||
"""
|
||||
return Direction([8, 2, 0, 6][self.get_index() % 4])
|
||||
|
||||
def get_peng_zu_earth_branch(self) -> PengZuEarthBranch:
|
||||
"""
|
||||
:return: 地支彭祖百忌 PengZuEarthBranch
|
||||
"""
|
||||
return PengZuEarthBranch(self.get_index())
|
||||
|
||||
def get_combine(self) -> EarthBranch:
|
||||
"""
|
||||
六合(子丑合,寅亥合,卯戌合,辰酉合,巳申合,午未合)
|
||||
:return: 地支 EarthBranch
|
||||
"""
|
||||
return EarthBranch(1 - self.get_index())
|
||||
|
||||
def get_harm(self) -> EarthBranch:
|
||||
"""
|
||||
六害(子未害、丑午害、寅巳害、卯辰害、申亥害、酉戌害)
|
||||
:return: 地支 EarthBranch
|
||||
"""
|
||||
return EarthBranch(19 - self.get_index())
|
||||
|
||||
def combine(self, target: EarthBranch) -> Union[Element, None]:
|
||||
"""
|
||||
合化
|
||||
子丑合化土,寅亥合化木,卯戌合化火,辰酉合化金,巳申合化水,午未合化火
|
||||
:param target: 地支 EarthBranch
|
||||
:return: 能合化则返回五行属性,不能合化则返回None
|
||||
"""
|
||||
return Element([2, 2, 0, 1, 3, 4, 2, 2, 4, 3, 1, 0][self.get_index()]) if self.get_combine() == target else None
|
||||
|
||||
|
||||
class HeavenStem(LoopTyme):
|
||||
"""天干(天元)"""
|
||||
NAMES: List[str] = ['甲', '乙', '丙', '丁', '戊', '己', '庚', '辛', '壬', '癸']
|
||||
"""名称"""
|
||||
|
||||
def __init__(self, index_or_name: Union[int, str]):
|
||||
super().__init__(self.NAMES, index_or_name)
|
||||
|
||||
@classmethod
|
||||
def from_name(cls, name: str) -> HeavenStem:
|
||||
return cls(name)
|
||||
|
||||
@classmethod
|
||||
def from_index(cls, index: int) -> HeavenStem:
|
||||
return cls(index)
|
||||
|
||||
def next(self, n: int) -> HeavenStem:
|
||||
return HeavenStem(self.next_index(n))
|
||||
|
||||
def get_element(self) -> Element:
|
||||
"""
|
||||
五行
|
||||
:return: 五行
|
||||
"""
|
||||
return Element(self.get_index() // 2)
|
||||
|
||||
def get_yin_yang(self) -> YinYang:
|
||||
"""
|
||||
:return: 阴阳
|
||||
"""
|
||||
return YinYang.YANG if self.get_index() % 2 == 0 else YinYang.YIN
|
||||
|
||||
def get_ten_star(self, target: HeavenStem) -> TenStar:
|
||||
"""
|
||||
十神(生我者,正印偏印。我生者,伤官食神。克我者,正官七杀。我克者,正财偏财。同我者,劫财比肩。)
|
||||
:param target: 天干
|
||||
:return:十神
|
||||
"""
|
||||
target_index: int = target.get_index()
|
||||
offset: int = target_index - self.get_index()
|
||||
if self.get_index() % 2 != 0 and target_index % 2 == 0:
|
||||
offset += 2
|
||||
return TenStar(offset)
|
||||
|
||||
def get_direction(self) -> Direction:
|
||||
"""
|
||||
:return: 方位
|
||||
"""
|
||||
return self.get_element().get_direction()
|
||||
|
||||
def get_joy_direction(self) -> Direction:
|
||||
"""
|
||||
喜神方位(《喜神方位歌》甲己在艮乙庚乾,丙辛坤位喜神安。丁壬只在离宫坐,戊癸原在在巽间。)
|
||||
:return: 方位
|
||||
"""
|
||||
return Direction([7, 5, 1, 8, 3][self.get_index() % 5])
|
||||
|
||||
def get_yang_direction(self) -> Direction:
|
||||
"""
|
||||
阳贵神方位(《阳贵神歌》甲戊坤艮位,乙己是坤坎,庚辛居离艮,丙丁兑与乾,震巽属何日,壬癸贵神安。)
|
||||
:return: 方位
|
||||
"""
|
||||
return Direction([1, 1, 6, 5, 7, 0, 8, 7, 2, 3][self.get_index()])
|
||||
|
||||
def get_yin_direction(self) -> Direction:
|
||||
"""
|
||||
阴贵神方位(《阴贵神歌》甲戊见牛羊,乙己鼠猴乡,丙丁猪鸡位,壬癸蛇兔藏,庚辛逢虎马,此是贵神方。)
|
||||
:return: 方位
|
||||
"""
|
||||
return Direction([7, 0, 5, 6, 1, 1, 7, 8, 3, 2][self.get_index()])
|
||||
|
||||
def get_wealth_direction(self) -> Direction:
|
||||
"""
|
||||
财神方位(《财神方位歌》甲乙东北是财神,丙丁向在西南寻,戊己正北坐方位,庚辛正东去安身,壬癸原来正南坐,便是财神方位真。)
|
||||
:return:方位
|
||||
"""
|
||||
return Direction([7, 1, 0, 2, 8][self.get_index() // 2])
|
||||
|
||||
def get_mascot_direction(self) -> Direction:
|
||||
"""
|
||||
福神方位(《福神方位歌》甲乙东南是福神,丙丁正东是堪宜,戊北己南庚辛坤,壬在乾方癸在西。)
|
||||
:return:方位
|
||||
"""
|
||||
return Direction([3, 3, 2, 2, 0, 8, 1, 1, 5, 6][self.get_index()])
|
||||
|
||||
def get_peng_zu_heaven_stem(self) -> PengZuHeavenStem:
|
||||
"""
|
||||
:return:天干彭祖百忌
|
||||
"""
|
||||
return PengZuHeavenStem(self.get_index())
|
||||
|
||||
def get_terrain(self, earth_branch: EarthBranch) -> Terrain:
|
||||
"""
|
||||
长生十二神(地势)
|
||||
长生十二神可通过不同的组合,得到自坐和星运
|
||||
:param: 地支
|
||||
:return:地势(长生十二神)
|
||||
"""
|
||||
earth_branch_index: int = earth_branch.get_index()
|
||||
return Terrain([1, 6, 10, 9, 10, 9, 7, 0, 4, 3][self.get_index()] + (earth_branch_index if YinYang.YANG == self.get_yin_yang() else -earth_branch_index))
|
||||
|
||||
def get_combine(self) -> HeavenStem:
|
||||
"""
|
||||
天干五合(甲己合,乙庚合,丙辛合,丁壬合,戊癸合)
|
||||
:return: 天干
|
||||
"""
|
||||
return self.next(5)
|
||||
|
||||
def combine(self, target: HeavenStem) -> Element:
|
||||
"""
|
||||
合化(甲己合化土 乙庚合化金 丙辛合化水 丁壬合化木 戊癸合化火)
|
||||
:param target: 天干
|
||||
:return: 能合化则返回五行属性,不能合化则返回None
|
||||
"""
|
||||
return Element(self.get_index() + 2) if self.get_combine() == target else None
|
||||
|
||||
|
||||
class HideHeavenStem(AbstractCulture):
|
||||
"""藏干(即人元,司令取天干,分野取天干的五行)"""
|
||||
|
||||
def __init__(self, heaven_stem: Union[HeavenStem, str, int], hide_heaven_stem_type: HideHeavenStemType):
|
||||
if isinstance(heaven_stem, int) or isinstance(heaven_stem, str):
|
||||
self._heaven_stem = HeavenStem(heaven_stem)
|
||||
else:
|
||||
self._heaven_stem = heaven_stem
|
||||
self._type = hide_heaven_stem_type
|
||||
|
||||
def get_name(self) -> str:
|
||||
return self._heaven_stem.get_name()
|
||||
|
||||
def get_heaven_stem(self) -> HeavenStem:
|
||||
"""
|
||||
天干
|
||||
:return: 天干
|
||||
"""
|
||||
return self._heaven_stem
|
||||
|
||||
def get_type(self) -> HideHeavenStemType:
|
||||
"""
|
||||
藏干类型
|
||||
:return: 藏干类型
|
||||
"""
|
||||
return self._type
|
||||
|
||||
|
||||
class HideHeavenStemDay(AbstractCultureDay):
|
||||
"""人元司令分野(地支藏干+天索引)"""
|
||||
|
||||
def __init__(self, hide_heaven_stem: HideHeavenStem, day_index: int):
|
||||
super().__init__(hide_heaven_stem, day_index)
|
||||
|
||||
def get_hide_heaven_stem(self) -> HideHeavenStem:
|
||||
"""
|
||||
:return: 藏干
|
||||
"""
|
||||
return self.get_culture()
|
||||
|
||||
def get_name(self) -> str:
|
||||
heaven_stem: HeavenStem = self.get_hide_heaven_stem().get_heaven_stem()
|
||||
return f'{heaven_stem.get_name()}{heaven_stem.get_element().get_name()}'
|
||||
|
||||
|
||||
class SixtyCycle(LoopTyme):
|
||||
"""六十甲子(六十干支周)"""
|
||||
_NAMES: List[str] = ['甲子', '乙丑', '丙寅', '丁卯', '戊辰', '己巳', '庚午', '辛未', '壬申', '癸酉', '甲戌', '乙亥', '丙子', '丁丑', '戊寅', '己卯', '庚辰', '辛巳', '壬午', '癸未', '甲申', '乙酉', '丙戌', '丁亥', '戊子', '己丑', '庚寅', '辛卯', '壬辰', '癸巳', '甲午', '乙未', '丙申', '丁酉', '戊戌', '己亥', '庚子', '辛丑', '壬寅', '癸卯', '甲辰', '乙巳', '丙午', '丁未', '戊申', '己酉', '庚戌', '辛亥', '壬子', '癸丑', '甲寅', '乙卯', '丙辰', '丁巳', '戊午', '己未', '庚申', '辛酉', '壬戌', '癸亥']
|
||||
"""名称"""
|
||||
|
||||
def __init__(self, index_or_name: Union[int, str]):
|
||||
super().__init__(self._NAMES, index_or_name)
|
||||
|
||||
@classmethod
|
||||
def from_name(cls, name: str) -> SixtyCycle:
|
||||
return cls(name)
|
||||
|
||||
@classmethod
|
||||
def from_index(cls, index: int) -> SixtyCycle:
|
||||
return cls(index)
|
||||
|
||||
def next(self, n: int) -> SixtyCycle:
|
||||
return SixtyCycle(self.next_index(n))
|
||||
|
||||
def get_heaven_stem(self) -> HeavenStem:
|
||||
"""
|
||||
天干
|
||||
:return: 天干
|
||||
"""
|
||||
return HeavenStem(self.get_index() % 10)
|
||||
|
||||
def get_earth_branch(self) -> EarthBranch:
|
||||
"""
|
||||
地支
|
||||
:return: 地支
|
||||
"""
|
||||
return EarthBranch(self.get_index() % 12)
|
||||
|
||||
def get_sound(self) -> Sound:
|
||||
"""
|
||||
纳音
|
||||
:return: 纳音
|
||||
"""
|
||||
return Sound(self.get_index() // 2)
|
||||
|
||||
def get_peng_zu(self) -> PengZu:
|
||||
"""
|
||||
彭祖百忌
|
||||
:return: 彭祖百忌
|
||||
"""
|
||||
return PengZu(self)
|
||||
|
||||
def get_ten(self) -> Ten:
|
||||
"""
|
||||
旬
|
||||
:return: 旬
|
||||
"""
|
||||
return Ten((self.get_heaven_stem().get_index() - self.get_earth_branch().get_index()) // 2)
|
||||
|
||||
def get_extra_earth_branches(self) -> List[EarthBranch]:
|
||||
"""
|
||||
旬空(空亡),因地支比天干多2个,旬空则为每一轮干支一一配对后多出来的2个地支
|
||||
:return: 旬空(空亡)
|
||||
"""
|
||||
earth_branch: EarthBranch = EarthBranch(10 + self.get_earth_branch().get_index() - self.get_heaven_stem().get_index())
|
||||
return [earth_branch, earth_branch.next(1)]
|
||||
|
||||
|
||||
class SixtyCycleYear(AbstractTyme):
|
||||
"""
|
||||
干支年
|
||||
"""
|
||||
|
||||
def __init__(self, year: int):
|
||||
if year < -1 or year > 9999:
|
||||
raise ValueError(f'illegal sixty cycle year: {year}')
|
||||
self._year = year
|
||||
|
||||
@classmethod
|
||||
def from_year(cls, year: int) -> SixtyCycleYear:
|
||||
return cls(year)
|
||||
|
||||
def get_year(self) -> int:
|
||||
"""
|
||||
年
|
||||
:return: 干支年数字,范围为-1到9999
|
||||
"""
|
||||
return self._year
|
||||
|
||||
def get_name(self) -> str:
|
||||
"""
|
||||
:return: {六十甲子}年
|
||||
"""
|
||||
return f'{self.get_sixty_cycle().get_name()}年'
|
||||
|
||||
def next(self, n: int) -> SixtyCycleYear:
|
||||
return SixtyCycleYear(self._year + n)
|
||||
|
||||
def get_sixty_cycle(self) -> SixtyCycle:
|
||||
"""
|
||||
干支
|
||||
:return: 干支 SixtyCycle
|
||||
"""
|
||||
return SixtyCycle(self._year - 4)
|
||||
|
||||
def get_twenty(self) -> Twenty:
|
||||
"""
|
||||
运
|
||||
:return: 运 Twenty
|
||||
"""
|
||||
return Twenty(floor((self._year - 1864) / 20))
|
||||
|
||||
def get_nine_star(self) -> NineStar:
|
||||
"""
|
||||
九星
|
||||
:return: 九星 NineStar
|
||||
"""
|
||||
return NineStar(63 + self.get_twenty().get_sixty().get_index() * 3 - self.get_sixty_cycle().get_index())
|
||||
|
||||
def get_jupiter_direction(self) -> Direction:
|
||||
"""
|
||||
太岁方位
|
||||
:return: 方位 Direction
|
||||
"""
|
||||
return Direction([0, 7, 7, 2, 3, 3, 8, 1, 1, 6, 0, 0][self.get_sixty_cycle().get_earth_branch().get_index()])
|
||||
|
||||
def get_first_month(self) -> SixtyCycleMonth:
|
||||
"""
|
||||
首月(依据五虎遁和正月起寅的规律)
|
||||
:return: 干支月
|
||||
"""
|
||||
return SixtyCycleMonth(self, SixtyCycle.from_index(self._year * 12 - 46))
|
||||
|
||||
def get_months(self) -> List[SixtyCycleMonth]:
|
||||
"""
|
||||
干支月列表
|
||||
:return: 干支月列表
|
||||
"""
|
||||
l: List[SixtyCycleMonth] = []
|
||||
m: SixtyCycleMonth = self.get_first_month()
|
||||
l.append(m)
|
||||
for i in range(1, 12):
|
||||
l.append(m.next(i))
|
||||
return l
|
||||
|
||||
|
||||
class SixtyCycleMonth(AbstractTyme):
|
||||
"""干支月"""
|
||||
|
||||
def __init__(self, year: SixtyCycleYear, month: SixtyCycle):
|
||||
"""
|
||||
:param year: 干支年
|
||||
:param month: 干支月
|
||||
"""
|
||||
self._year = year
|
||||
self._month = month
|
||||
|
||||
@classmethod
|
||||
def from_index(cls, year: int, index: int) -> SixtyCycleMonth:
|
||||
return SixtyCycleYear.from_year(year).get_first_month().next(index)
|
||||
|
||||
def get_sixty_cycle_year(self) -> SixtyCycleYear:
|
||||
"""
|
||||
干支年
|
||||
:return: 干支年
|
||||
"""
|
||||
return self._year
|
||||
|
||||
def get_year(self) -> SixtyCycle:
|
||||
"""
|
||||
年柱
|
||||
:return: 干支
|
||||
"""
|
||||
return self._year.get_sixty_cycle()
|
||||
|
||||
def get_sixty_cycle(self) -> SixtyCycle:
|
||||
"""
|
||||
干支
|
||||
:return: 干支
|
||||
"""
|
||||
return self._month
|
||||
|
||||
def get_index_in_year(self) -> int:
|
||||
"""
|
||||
位于当年的索引(0-11),寅月为0,依次类推
|
||||
:return: 数字,范围0到11,寅月为0,依次类推
|
||||
"""
|
||||
return self._month.get_earth_branch().next(-2).get_index()
|
||||
|
||||
def get_name(self) -> str:
|
||||
"""
|
||||
名称
|
||||
:return: 名称
|
||||
"""
|
||||
return f'{self._month}月'
|
||||
|
||||
def __str__(self) -> str:
|
||||
return f'{self._year}{self.get_name()}'
|
||||
|
||||
def next(self, n: int) -> SixtyCycleMonth:
|
||||
return SixtyCycleMonth(SixtyCycleYear.from_year((self._year.get_year()*12 + self.get_index_in_year() + n) // 12), self._month.next(n))
|
||||
|
||||
def get_first_day(self) -> SixtyCycleDay:
|
||||
from tyme4py.solar import SolarTerm
|
||||
return SixtyCycleDay.from_solar_day(SolarTerm.from_index(self._year.get_year(), 3+self.get_index_in_year()*2).get_solar_day())
|
||||
|
||||
def get_days(self) -> List[SixtyCycleDay]:
|
||||
"""
|
||||
本月的干支日列表
|
||||
:return: 支日列表
|
||||
"""
|
||||
l: List[SixtyCycleDay] = []
|
||||
d: SixtyCycleDay = self.get_first_day()
|
||||
while d.get_sixty_cycle_month() == self:
|
||||
l.append(d)
|
||||
d = d.next(1)
|
||||
return l
|
||||
|
||||
def get_nine_star(self) -> NineStar:
|
||||
"""
|
||||
:return: 九星 NineStar
|
||||
"""
|
||||
index = self._month.get_earth_branch().get_index()
|
||||
if index < 2:
|
||||
index += 3
|
||||
return NineStar(27 - self.get_year().get_earth_branch().get_index() % 3 * 3 - index)
|
||||
|
||||
def get_jupiter_direction(self) -> Direction:
|
||||
"""
|
||||
太岁方位
|
||||
:return: 方位 Direction
|
||||
"""
|
||||
n: int = [7, -1, 1, 3][self._month.get_earth_branch().next(-2).get_index() % 4]
|
||||
return self._month.get_heaven_stem().get_direction() if n == -1 else Direction(n)
|
||||
|
||||
|
||||
class SixtyCycleDay(AbstractTyme):
|
||||
"""干支日"""
|
||||
|
||||
def __init__(self, solar_day: SolarDay, month: SixtyCycleMonth, day: SixtyCycle):
|
||||
"""
|
||||
:param solar_day: 公历年
|
||||
:param month: 干支月
|
||||
:param day: 日柱
|
||||
"""
|
||||
self._solar_day = solar_day
|
||||
self._month = month
|
||||
self._day = day
|
||||
|
||||
@classmethod
|
||||
def from_solar_day(cls, solar_day: SolarDay) -> SixtyCycleDay:
|
||||
from tyme4py.solar import SolarTerm, SolarDay
|
||||
term: SolarTerm = solar_day.get_term()
|
||||
index: int = term.get_index()
|
||||
offset: int = -1
|
||||
if index < 3:
|
||||
if index == 0:
|
||||
offset = -2
|
||||
else:
|
||||
offset = (index - 3) // 2
|
||||
return cls(solar_day, SixtyCycleYear.from_year(term.get_year()).get_first_month().next(offset), SixtyCycle.from_index(solar_day.subtract(SolarDay.from_ymd(2000, 1, 7))))
|
||||
|
||||
def get_solar_day(self) -> SolarDay:
|
||||
"""
|
||||
:return: 公历日
|
||||
"""
|
||||
return self._solar_day
|
||||
|
||||
def get_sixty_cycle_month(self) -> SixtyCycleMonth:
|
||||
"""
|
||||
:return: 干支月
|
||||
"""
|
||||
return self._month
|
||||
|
||||
def get_year(self) -> SixtyCycle:
|
||||
"""
|
||||
年柱
|
||||
:return: 干支
|
||||
"""
|
||||
return self._month.get_year()
|
||||
|
||||
def get_month(self) -> SixtyCycle:
|
||||
"""
|
||||
月柱
|
||||
:return: 干支
|
||||
"""
|
||||
return self._month.get_sixty_cycle()
|
||||
|
||||
def get_sixty_cycle(self) -> SixtyCycle:
|
||||
"""
|
||||
干支
|
||||
:return: 干支
|
||||
"""
|
||||
return self._day
|
||||
|
||||
def get_name(self) -> str:
|
||||
return f'{self._day}日'
|
||||
|
||||
def __str__(self) -> str:
|
||||
return f'{self._month}{self.get_name()}'
|
||||
|
||||
def next(self, n: int) -> SixtyCycleDay:
|
||||
return SixtyCycleDay.from_solar_day(self._solar_day.next(n))
|
||||
|
||||
def get_duty(self) -> Duty:
|
||||
"""
|
||||
建除十二值神
|
||||
:return: 建除十二值神 Duty
|
||||
"""
|
||||
return Duty(self._day.get_earth_branch().get_index() - self.get_month().get_earth_branch().get_index())
|
||||
|
||||
def get_twelve_star(self) -> TwelveStar:
|
||||
"""
|
||||
黄道黑道十二神
|
||||
:return: 黄道黑道十二神 TwelveStar
|
||||
"""
|
||||
return TwelveStar(self._day.get_earth_branch().get_index() + (8 - self.get_month().get_earth_branch().get_index() % 6) * 2)
|
||||
|
||||
def get_nine_star(self) -> NineStar:
|
||||
"""
|
||||
九星
|
||||
:return: 九星 NineStar
|
||||
"""
|
||||
return self._solar_day.get_nine_star()
|
||||
|
||||
def get_jupiter_direction(self) -> Direction:
|
||||
"""
|
||||
太岁方位
|
||||
:return: 方位 Direction
|
||||
"""
|
||||
index: int = self._day.get_index()
|
||||
from tyme4py.culture import Element
|
||||
return Element(index // 12).get_direction() if index % 12 < 6 else self._month.get_sixty_cycle_year().get_jupiter_direction()
|
||||
|
||||
def get_fetus_day(self) -> FetusDay:
|
||||
"""
|
||||
逐日胎神
|
||||
:return:逐日胎神 FetusDay
|
||||
"""
|
||||
return FetusDay.from_sixty_cycle_day(self)
|
||||
|
||||
def get_twenty_eight_star(self) -> TwentyEightStar:
|
||||
"""
|
||||
二十八宿
|
||||
:return: 二十八宿 TwentyEightStar
|
||||
"""
|
||||
from tyme4py.culture.star.twentyeight import TwentyEightStar
|
||||
return TwentyEightStar(10 + 8 * self._solar_day.get_week().get_index()).next(-7 * self._day.get_earth_branch().get_index())
|
||||
|
||||
def get_gods(self) -> List[God]:
|
||||
"""
|
||||
神煞列表(吉神宜趋,凶神宜忌)
|
||||
:return: 神煞列表
|
||||
"""
|
||||
return God.get_day_gods(self.get_month(), self._day)
|
||||
|
||||
def get_recommends(self) -> List[Taboo]:
|
||||
"""
|
||||
今日 宜
|
||||
:return: 宜忌列表
|
||||
"""
|
||||
return Taboo.get_day_recommends(self.get_month(), self._day)
|
||||
|
||||
def get_avoids(self) -> List[Taboo]:
|
||||
"""
|
||||
今日 忌
|
||||
:return: 宜忌列表
|
||||
"""
|
||||
return Taboo.get_day_avoids(self.get_month(), self._day)
|
||||
|
||||
def get_hours(self) -> List[SixtyCycleHour]:
|
||||
"""
|
||||
当天的干支时辰列表
|
||||
:return: 干支时辰列表
|
||||
"""
|
||||
from tyme4py.solar import SolarDay, SolarTime
|
||||
l: List[SixtyCycleHour] = []
|
||||
d: SolarDay = self._solar_day.next(-1)
|
||||
t: SolarTime = SolarTime.from_ymd_hms(d.get_year(), d.get_month(), d.get_day(), 23, 0, 0)
|
||||
h: SixtyCycleHour = SixtyCycleHour.from_solar_time(t)
|
||||
l.append(h)
|
||||
for i in range(0, 11):
|
||||
h = h.next(7200)
|
||||
l.append(h)
|
||||
return l
|
||||
|
||||
def get_three_pillars(self) -> ThreePillars:
|
||||
return ThreePillars(self.get_year(), self.get_month(), self.get_sixty_cycle())
|
||||
|
||||
|
||||
class SixtyCycleHour(AbstractTyme):
|
||||
"""干支时辰"""
|
||||
|
||||
def __init__(self, solar_time: SolarTime):
|
||||
from tyme4py.solar import SolarTerm, SolarTime
|
||||
from tyme4py.lunar import LunarYear, LunarMonth, LunarDay, LunarHour
|
||||
solar_year: int = solar_time.get_year()
|
||||
spring_solar_time: SolarTime = SolarTerm.from_index(solar_year, 3).get_julian_day().get_solar_time()
|
||||
lunar_hour: LunarHour = solar_time.get_lunar_hour()
|
||||
lunar_day: LunarDay = lunar_hour.get_lunar_day()
|
||||
lunar_year: LunarYear = lunar_day.get_lunar_month().get_lunar_year()
|
||||
if lunar_year.get_year() == solar_year:
|
||||
if solar_time.is_before(spring_solar_time):
|
||||
lunar_year = lunar_year.next(-1)
|
||||
elif lunar_year.get_year() < solar_year:
|
||||
if not solar_time.is_before(spring_solar_time):
|
||||
lunar_year = lunar_year.next(1)
|
||||
|
||||
term: SolarTerm = solar_time.get_term()
|
||||
index: int = term.get_index() - 3
|
||||
if index < 0 and term.get_julian_day().get_solar_time().is_after(SolarTerm.from_index(solar_year, 3).get_julian_day().get_solar_time()):
|
||||
index += 24
|
||||
d: SixtyCycle = lunar_day.get_sixty_cycle()
|
||||
if solar_time.get_hour() == 23:
|
||||
d = d.next(1)
|
||||
y: SixtyCycleYear = SixtyCycleYear.from_year(lunar_year.get_year())
|
||||
m: LunarMonth = LunarMonth.from_ym(solar_year, 1)
|
||||
|
||||
self._solar_time = solar_time
|
||||
self._day = SixtyCycleDay(solar_time.get_solar_day(), SixtyCycleMonth(y, m.get_sixty_cycle().next(int(floor(index * 0.5)))), d)
|
||||
self._hour = lunar_hour.get_sixty_cycle()
|
||||
|
||||
@classmethod
|
||||
def from_solar_time(cls, solar_time: SolarTime) -> SixtyCycleHour:
|
||||
return cls(solar_time)
|
||||
|
||||
def get_year(self) -> SixtyCycle:
|
||||
"""
|
||||
年柱
|
||||
:return: 干支
|
||||
"""
|
||||
return self._day.get_year()
|
||||
|
||||
def get_month(self) -> SixtyCycle:
|
||||
"""
|
||||
月柱
|
||||
:return: 干支
|
||||
"""
|
||||
return self._day.get_month()
|
||||
|
||||
def get_day(self) -> SixtyCycle:
|
||||
"""
|
||||
日柱
|
||||
:return: 干支
|
||||
"""
|
||||
return self._day.get_sixty_cycle()
|
||||
|
||||
def get_sixty_cycle(self) -> SixtyCycle:
|
||||
"""
|
||||
干支
|
||||
:return: 干支
|
||||
"""
|
||||
return self._hour
|
||||
|
||||
def get_sixty_cycle_day(self) -> SixtyCycleDay:
|
||||
"""
|
||||
干支日
|
||||
:return: 干支日
|
||||
"""
|
||||
return self._day
|
||||
|
||||
def get_solar_time(self) -> SolarTime:
|
||||
"""
|
||||
公历时刻
|
||||
:return: 公历时刻
|
||||
"""
|
||||
return self._solar_time
|
||||
|
||||
def get_name(self) -> str:
|
||||
return f'{self._hour}时'
|
||||
|
||||
def __str__(self) -> str:
|
||||
return f'{self._day}{self.get_name()}'
|
||||
|
||||
def get_index_in_day(self) -> int:
|
||||
"""
|
||||
位于当天的索引
|
||||
:return: 位于当天的索引
|
||||
"""
|
||||
h: int = self._solar_time.get_hour()
|
||||
if h == 23:
|
||||
return 0
|
||||
return (h + 1) // 2
|
||||
|
||||
def next(self, n: int) -> SixtyCycleHour:
|
||||
return SixtyCycleHour.from_solar_time(self._solar_time.next(n))
|
||||
|
||||
def get_twelve_star(self) -> TwelveStar:
|
||||
"""
|
||||
黄道黑道十二神
|
||||
:return: 黄道黑道十二神 TwelveStar
|
||||
"""
|
||||
return TwelveStar(self._hour.get_earth_branch().get_index() + (8 - self.get_day().get_earth_branch().get_index() % 6) * 2)
|
||||
|
||||
def get_nine_star(self) -> NineStar:
|
||||
"""
|
||||
九星(时家紫白星歌诀:三元时白最为佳,冬至阳生顺莫差,孟日七宫仲一白,季日四绿发萌芽,每把时辰起甲子,本时星耀照光华,时星移入中宫去,顺飞八方逐细查。夏至阴生逆回首,孟归三碧季加六,仲在九宫时起甲,依然掌中逆轮跨。)
|
||||
:return: 九星 NineStar
|
||||
"""
|
||||
from tyme4py.solar import SolarTerm, SolarDay
|
||||
solar: SolarDay = self._solar_time.get_solar_day()
|
||||
dong_zhi: SolarTerm = SolarTerm(solar.get_year(), 0)
|
||||
earth_branch_index: int = self.get_index_in_day() % 12
|
||||
index: int = 8 - 3 * (self.get_day().get_earth_branch().get_index() % 3)
|
||||
if (not solar.is_before(dong_zhi.get_julian_day().get_solar_day())) and solar.is_before(dong_zhi.next(12).get_julian_day().get_solar_day()):
|
||||
index = 8 + earth_branch_index - index
|
||||
else:
|
||||
index -= earth_branch_index
|
||||
return NineStar(index)
|
||||
|
||||
def get_eight_char(self) -> EightChar:
|
||||
"""
|
||||
八字
|
||||
:return: 八字
|
||||
"""
|
||||
return EightChar(self.get_year(), self.get_month(), self.get_day(), self._hour)
|
||||
|
||||
def get_recommends(self) -> List[Taboo]:
|
||||
"""
|
||||
时辰 宜
|
||||
:return: 宜忌列表
|
||||
"""
|
||||
return Taboo.get_hour_recommends(self.get_day(), self._hour)
|
||||
|
||||
def get_avoids(self) -> List[Taboo]:
|
||||
"""
|
||||
时辰 忌
|
||||
:return: 宜忌列表
|
||||
"""
|
||||
return Taboo.get_hour_avoids(self.get_day(), self._hour)
|
||||
Vendored
+918
@@ -0,0 +1,918 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
from __future__ import annotations
|
||||
|
||||
from math import floor, ceil
|
||||
from typing import TYPE_CHECKING, Union, List
|
||||
|
||||
from tyme4py import LoopTyme, AbstractCultureDay
|
||||
from tyme4py.culture import Week, Constellation, PhaseDay, Phase
|
||||
from tyme4py.culture.dog import DogDay, Dog
|
||||
from tyme4py.culture.nine import NineDay, Nine
|
||||
from tyme4py.culture.phenology import PhenologyDay, Phenology
|
||||
from tyme4py.culture.plumrain import PlumRainDay, PlumRain
|
||||
from tyme4py.culture.star.nine import NineStar
|
||||
from tyme4py.enums import HideHeavenStemType
|
||||
from tyme4py.event import Event
|
||||
from tyme4py.unit import YearUnit, MonthUnit, WeekUnit, DayUnit, SecondUnit
|
||||
from tyme4py.util import ShouXingUtil
|
||||
from tyme4py.jd import JulianDay
|
||||
from tyme4py.festival import SolarFestival
|
||||
from tyme4py.holiday import LegalHoliday
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from tyme4py.lunar import LunarDay, LunarMonth, LunarHour
|
||||
from tyme4py.sixtycycle import HideHeavenStemDay, SixtyCycleDay, SixtyCycleHour
|
||||
from tyme4py.rabbyung import RabByungYear, RabByungDay
|
||||
from tyme4py.hijri import HijriDay
|
||||
|
||||
|
||||
class SolarTerm(LoopTyme):
|
||||
"""节气"""
|
||||
NAMES: List[str] = ['冬至', '小寒', '大寒', '立春', '雨水', '惊蛰', '春分', '清明', '谷雨', '立夏', '小满', '芒种', '夏至', '小暑', '大暑', '立秋', '处暑', '白露', '秋分', '寒露', '霜降', '立冬', '小雪', '大雪']
|
||||
"""名称"""
|
||||
|
||||
def __init__(self, year: int, index_or_name: Union[int, str]):
|
||||
super().__init__(self.NAMES, index_or_name)
|
||||
y = year
|
||||
if isinstance(index_or_name, int):
|
||||
size = self.NAMES.__len__()
|
||||
y = (year * size + index_or_name) // size
|
||||
jd = floor((y - 2000) * 365.2422 + 180)
|
||||
# 355对应2000.12冬至,计算粗略估计值
|
||||
w = floor((jd - 355 + 183) / 365.2422) * 365.2422 + 355
|
||||
if ShouXingUtil.calc_qi(w) > jd:
|
||||
w -= 365.2422
|
||||
self._year = y
|
||||
self._cursory_julian_day = ShouXingUtil.calc_qi(w + 15.2184 * self.get_index())
|
||||
|
||||
@classmethod
|
||||
def from_index(cls, year: int, index: int) -> SolarTerm:
|
||||
return cls(year, index)
|
||||
|
||||
@classmethod
|
||||
def from_name(cls, year: int, name: str) -> SolarTerm:
|
||||
return cls(year, name)
|
||||
|
||||
def next(self, n: int) -> SolarTerm:
|
||||
size = self.get_size()
|
||||
i = self.get_index() + n
|
||||
return SolarTerm((self._year * size + i) // size, self._index_of_by(i))
|
||||
|
||||
def is_jie(self) -> bool:
|
||||
"""是否节令"""
|
||||
return self._index % 2 == 1
|
||||
|
||||
def is_qi(self) -> bool:
|
||||
"""是否气令"""
|
||||
return self._index % 2 == 0
|
||||
|
||||
def get_julian_day(self) -> JulianDay:
|
||||
"""
|
||||
儒略日(精确到秒)
|
||||
:return : 儒略日
|
||||
"""
|
||||
return JulianDay.from_julian_day(ShouXingUtil.qi_accurate2(self._cursory_julian_day) + JulianDay.J2000)
|
||||
|
||||
def get_solar_day(self) -> SolarDay:
|
||||
"""
|
||||
公历日(用于日历)
|
||||
@return: 公历日
|
||||
"""
|
||||
return JulianDay.from_julian_day(self._cursory_julian_day + JulianDay.J2000).get_solar_day()
|
||||
|
||||
def get_year(self) -> int:
|
||||
return self._year
|
||||
|
||||
def get_cursory_julian_day(self) -> float:
|
||||
"""
|
||||
儒略日(用于日历,只精确到日中午12:00)
|
||||
@return: 儒略日
|
||||
"""
|
||||
return self._cursory_julian_day
|
||||
|
||||
|
||||
class SolarTermDay(AbstractCultureDay):
|
||||
"""节气第几天"""
|
||||
|
||||
def __init__(self, solar_term: SolarTerm, day_index: int):
|
||||
super().__init__(solar_term, day_index)
|
||||
|
||||
def get_solar_term(self) -> SolarTerm:
|
||||
"""
|
||||
:return: 节气
|
||||
"""
|
||||
return self.get_culture()
|
||||
|
||||
|
||||
class SolarYear(YearUnit):
|
||||
"""公历年"""
|
||||
|
||||
def __init__(self, year: int):
|
||||
SolarYear.validate(year)
|
||||
super().__init__(year)
|
||||
|
||||
@staticmethod
|
||||
def validate(year: int) -> None:
|
||||
if year < 1 or year > 9999:
|
||||
raise ValueError(f'illegal solar year: {year}')
|
||||
|
||||
@classmethod
|
||||
def from_year(cls, year: int) -> SolarYear:
|
||||
return cls(year)
|
||||
|
||||
def get_day_count(self) -> int:
|
||||
if self._year == 1582:
|
||||
return 355
|
||||
return 366 if self.is_leap() else 365
|
||||
|
||||
def is_leap(self) -> bool:
|
||||
if self._year < 1600:
|
||||
return self._year % 4 == 0
|
||||
return (self._year % 4 == 0 and self._year % 100 != 0) or (self._year % 400 == 0)
|
||||
|
||||
def get_name(self) -> str:
|
||||
return f"{self._year}年"
|
||||
|
||||
def next(self, n: int) -> SolarYear:
|
||||
return SolarYear.from_year(self._year + n)
|
||||
|
||||
def get_months(self) -> List[SolarMonth]:
|
||||
return [SolarMonth.from_ym(self._year, month) for month in range(1, 13)]
|
||||
|
||||
def get_seasons(self) -> List[SolarSeason]:
|
||||
return [SolarSeason.from_index(self._year, i) for i in range(4)]
|
||||
|
||||
def get_half_years(self) -> List[SolarHalfYear]:
|
||||
return [SolarHalfYear.from_index(self._year, i) for i in range(2)]
|
||||
|
||||
def get_rab_byung_year(self) -> RabByungYear:
|
||||
from tyme4py.rabbyung import RabByungYear
|
||||
return RabByungYear.from_year(self._year)
|
||||
|
||||
|
||||
class SolarHalfYear(YearUnit):
|
||||
"""公历半年"""
|
||||
NAMES: List[str] = ['上半年', '下半年']
|
||||
|
||||
@staticmethod
|
||||
def validate(year: int, index: int) -> None:
|
||||
if index < 0 or index > 1:
|
||||
raise ValueError(f'illegal solar half year index: {index}')
|
||||
SolarYear.validate(year)
|
||||
|
||||
def __init__(self, year: int, index: int):
|
||||
SolarHalfYear.validate(year, index)
|
||||
super().__init__(year)
|
||||
self._index = index
|
||||
|
||||
@classmethod
|
||||
def from_index(cls, year: int, index: int) -> SolarHalfYear:
|
||||
return cls(year, index)
|
||||
|
||||
def get_solar_year(self) -> SolarYear:
|
||||
return SolarYear.from_year(self._year)
|
||||
|
||||
def get_index(self) -> int:
|
||||
return self._index
|
||||
|
||||
def get_name(self) -> str:
|
||||
return self.NAMES[self._index]
|
||||
|
||||
def __str__(self) -> str:
|
||||
return f'{self.get_solar_year()}{self.get_name()}'
|
||||
|
||||
def next(self, n: int) -> SolarHalfYear:
|
||||
i = self._index + n
|
||||
return SolarHalfYear.from_index((self.get_year() * 2 + i) // 2, self.index_of(i, 2))
|
||||
|
||||
def get_months(self) -> List[SolarMonth]:
|
||||
y = self.get_year()
|
||||
return [SolarMonth.from_ym(y, self._index * 6 + i) for i in range(1, 7)]
|
||||
|
||||
def get_seasons(self) -> List[SolarSeason]:
|
||||
y = self.get_year()
|
||||
return [SolarSeason.from_index(y, self._index * 2 + i) for i in range(2)]
|
||||
|
||||
|
||||
class SolarSeason(YearUnit):
|
||||
"""公历季度"""
|
||||
NAMES: List[str] = ['一季度', '二季度', '三季度', '四季度']
|
||||
|
||||
@staticmethod
|
||||
def validate(year: int, index: int) -> None:
|
||||
if index < 0 or index > 3:
|
||||
raise ValueError(f'illegal solar season index: {index}')
|
||||
SolarYear.validate(year)
|
||||
|
||||
def __init__(self, year: int, index: int):
|
||||
SolarSeason.validate(year, index)
|
||||
super().__init__(year)
|
||||
self._index = index
|
||||
|
||||
@classmethod
|
||||
def from_index(cls, year: int, index: int) -> SolarSeason:
|
||||
return cls(year, index)
|
||||
|
||||
def get_solar_year(self) -> SolarYear:
|
||||
return SolarYear.from_year(self._year)
|
||||
|
||||
def get_index(self) -> int:
|
||||
return self._index
|
||||
|
||||
def get_name(self) -> str:
|
||||
return self.NAMES[self._index]
|
||||
|
||||
def __str__(self) -> str:
|
||||
return f'{self.get_solar_year()}{self.get_name()}'
|
||||
|
||||
def next(self, n: int) -> SolarSeason:
|
||||
i = self._index + n
|
||||
return SolarSeason.from_index((self.get_year() * 4 + i) // 4, self.index_of(i, 4))
|
||||
|
||||
def get_months(self) -> List[SolarMonth]:
|
||||
y = self.get_year()
|
||||
return [SolarMonth.from_ym(y, self._index * 3 + i) for i in range(1, 4)]
|
||||
|
||||
|
||||
class SolarMonth(MonthUnit):
|
||||
"""公历月"""
|
||||
NAMES: List[str] = ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月']
|
||||
_DAYS: List[int] = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
|
||||
"""每月天数"""
|
||||
|
||||
@staticmethod
|
||||
def validate(year: int, month: int) -> None:
|
||||
if month < 1 or month > 12:
|
||||
raise ValueError(f'illegal solar month: {month}')
|
||||
SolarYear.validate(year)
|
||||
|
||||
def __init__(self, year: int, month: int):
|
||||
"""
|
||||
:param year: 年
|
||||
:param month: 月
|
||||
"""
|
||||
SolarMonth.validate(year, month)
|
||||
super().__init__(year, month)
|
||||
|
||||
@classmethod
|
||||
def from_ym(cls, year: int, month: int) -> SolarMonth:
|
||||
return cls(year, month)
|
||||
|
||||
def get_solar_year(self) -> SolarYear:
|
||||
"""
|
||||
:return: 公历年
|
||||
"""
|
||||
return SolarYear.from_year(self._year)
|
||||
|
||||
def get_day_count(self) -> int:
|
||||
"""
|
||||
当月的总天数
|
||||
:return: 天数(1582年10月只有21天)
|
||||
"""
|
||||
if 1582 == self._year and 10 == self._month:
|
||||
return 21
|
||||
d: int = self._DAYS[self.get_index_in_year()]
|
||||
# 公历闰年2月多一天
|
||||
if 2 == self._month and self.get_solar_year().is_leap():
|
||||
d += 1
|
||||
return d
|
||||
|
||||
def get_index_in_year(self) -> int:
|
||||
"""
|
||||
位于当年的月索引
|
||||
:return: 位于当年的索引(0-11)
|
||||
"""
|
||||
return self._month - 1
|
||||
|
||||
def get_season(self) -> SolarSeason:
|
||||
"""
|
||||
:return: 公历季度 SolarSeason
|
||||
"""
|
||||
return SolarSeason(self._year, int(self.get_index_in_year() / 3))
|
||||
|
||||
def get_week_count(self, start: int) -> int:
|
||||
"""
|
||||
当月有几周
|
||||
:param start:起始星期,1234560分别代表星期一至星期天
|
||||
:return:周数
|
||||
"""
|
||||
return ceil((self.index_of(SolarDay(self._year, self._month, 1).get_week().get_index() - start, 7) + self.get_day_count()) / 7)
|
||||
|
||||
def get_name(self) -> str:
|
||||
return self.NAMES[self.get_index_in_year()]
|
||||
|
||||
def __str__(self) -> str:
|
||||
return f'{self.get_solar_year()}{self.get_name()}'
|
||||
|
||||
def next(self, n: int) -> SolarMonth:
|
||||
i: int = self._month - 1 + n
|
||||
return SolarMonth((self._year * 12 + i) // 12, self.index_of(i, 12) + 1)
|
||||
|
||||
def get_weeks(self, start: int) -> List[SolarWeek]:
|
||||
"""
|
||||
本月的公历周列表
|
||||
:param start: 星期几作为一周的开始,1234560分别代表星期一至星期天
|
||||
:return: 周列表
|
||||
"""
|
||||
l: List[SolarWeek] = []
|
||||
for i in range(0, self.get_week_count(start)):
|
||||
l.append(SolarWeek(self._year, self._month, i, start))
|
||||
return l
|
||||
|
||||
def get_days(self) -> List[SolarDay]:
|
||||
"""
|
||||
本月的公历日列表
|
||||
:return: 公历日 SolarDay 的列表,从1日开始
|
||||
"""
|
||||
l: List[SolarDay] = []
|
||||
for i in range(1, self.get_day_count()):
|
||||
l.append(SolarDay(self._year, self._month, i))
|
||||
return l
|
||||
|
||||
def get_first_day(self) -> SolarDay:
|
||||
"""
|
||||
本月第一天
|
||||
:return: 公历日 SolarDay
|
||||
"""
|
||||
return SolarDay.from_ymd(self._year, self._month, 1)
|
||||
|
||||
|
||||
class SolarWeek(WeekUnit):
|
||||
"""公历周"""
|
||||
|
||||
@staticmethod
|
||||
def validate(year: int, month: int, index: int, start: int) -> None:
|
||||
WeekUnit.validate(year, month, index, start)
|
||||
m: SolarMonth = SolarMonth(year, month)
|
||||
if index >= m.get_week_count(start):
|
||||
raise ValueError(f'illegal solar week index: {index} in month: {m}')
|
||||
|
||||
def __init__(self, year: int, month: int, index: int, start: int):
|
||||
"""
|
||||
:param year: 年
|
||||
:param month: 月
|
||||
:param index: 索引,0-5
|
||||
:param start: 起始星期,1234560分别代表星期一至星期天
|
||||
"""
|
||||
SolarWeek.validate(year, month, index, start)
|
||||
super().__init__(year, month, index, start)
|
||||
|
||||
@classmethod
|
||||
def from_ym(cls, year: int, month: int, index: int, start: int) -> SolarWeek:
|
||||
return cls(year, month, index, start)
|
||||
|
||||
def get_solar_month(self) -> SolarMonth:
|
||||
"""
|
||||
:return: 公历月
|
||||
"""
|
||||
return SolarMonth.from_ym(self._year, self._month)
|
||||
|
||||
def get_index_in_year(self) -> int:
|
||||
"""
|
||||
位于当年的索引
|
||||
:return: 索引 注意:索引值是从0开始,即0代表第一周
|
||||
"""
|
||||
i: int = 0
|
||||
# 本周第1天
|
||||
first_day: SolarDay = self.get_first_day()
|
||||
# 今年第1周
|
||||
w: SolarWeek = SolarWeek(self._year, 1, 0, self._start)
|
||||
while not w.get_first_day() == first_day:
|
||||
w = w.next(1)
|
||||
i += 1
|
||||
return i
|
||||
|
||||
def get_name(self) -> str:
|
||||
return self.NAMES[self._index]
|
||||
|
||||
def __str__(self) -> str:
|
||||
return f'{self.get_solar_month()}{self.get_name()}'
|
||||
|
||||
def next(self, n: int) -> SolarWeek:
|
||||
d: int = self._index + n
|
||||
m: SolarMonth = self.get_solar_month()
|
||||
if n > 0:
|
||||
week_count: int = m.get_week_count(self._start)
|
||||
while d >= week_count:
|
||||
d -= week_count
|
||||
m = m.next(1)
|
||||
if m.get_first_day().get_week().get_index() != self._start:
|
||||
d += 1
|
||||
week_count = m.get_week_count(self._start)
|
||||
elif n < 0:
|
||||
while d < 0:
|
||||
if m.get_first_day().get_week().get_index() != self._start:
|
||||
d -= 1
|
||||
m = m.next(-1)
|
||||
d += m.get_week_count(self._start)
|
||||
return SolarWeek(m.get_year(), m.get_month(), d, self._start)
|
||||
|
||||
def get_first_day(self) -> SolarDay:
|
||||
"""
|
||||
本周第1天
|
||||
:return: 公历日
|
||||
"""
|
||||
first_day: SolarDay = SolarDay(self._year, self._month, 1)
|
||||
return first_day.next(self._index * 7 - self.index_of(first_day.get_week().get_index() - self._start, 7))
|
||||
|
||||
def get_days(self) -> List[SolarDay]:
|
||||
"""
|
||||
本周公历日列表
|
||||
:return: 公历日列表
|
||||
"""
|
||||
l: List[SolarDay] = []
|
||||
d: SolarDay = self.get_first_day()
|
||||
l.append(d)
|
||||
for i in range(1, 7):
|
||||
l.append(d.next(i))
|
||||
return l
|
||||
|
||||
def __eq__(self, o: SolarWeek) -> bool:
|
||||
return o and o.get_first_day() == self.get_first_day()
|
||||
|
||||
|
||||
class SolarDay(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日', '31日']
|
||||
|
||||
@staticmethod
|
||||
def validate(year: int, month: int, day: int) -> None:
|
||||
if day < 1:
|
||||
raise ValueError(f'illegal solar day: {year}-{month}-{day}')
|
||||
if 1582 == year and 10 == month:
|
||||
if (4 < day < 15) or day > 31:
|
||||
raise ValueError(f'illegal solar day: {year}-{month}-{day}')
|
||||
elif day > SolarMonth.from_ym(year, month).get_day_count():
|
||||
raise ValueError(f'illegal solar day: {year}-{month}-{day}')
|
||||
|
||||
def __init__(self, year: int, month: int, day: int):
|
||||
SolarDay.validate(year, month, day)
|
||||
super().__init__(year, month, day)
|
||||
|
||||
@classmethod
|
||||
def from_ymd(cls, year: int, month: int, day: int) -> SolarDay:
|
||||
return cls(year, month, day)
|
||||
|
||||
def get_solar_month(self) -> SolarMonth:
|
||||
"""
|
||||
:return: 公历月
|
||||
"""
|
||||
return SolarMonth.from_ym(self._year, self._month)
|
||||
|
||||
def get_week(self) -> Week:
|
||||
"""
|
||||
:return: 星期
|
||||
"""
|
||||
return self.get_julian_day().get_week()
|
||||
|
||||
def get_constellation(self) -> Constellation:
|
||||
"""
|
||||
:return: 星座 Constellation
|
||||
"""
|
||||
m: int = self._month - 1
|
||||
offset: int = 1 if self._day > [19, 18, 20, 19, 20, 21, 22, 22, 22, 23, 22, 21][m] else 0
|
||||
return Constellation.from_index(9 + m + offset)
|
||||
|
||||
def get_name(self) -> str:
|
||||
return self.NAMES[self._day - 1]
|
||||
|
||||
def __str__(self) -> str:
|
||||
return f'{self.get_solar_month()}{self.get_name()}'
|
||||
|
||||
def next(self, n: int) -> SolarDay:
|
||||
return self.get_julian_day().next(n).get_solar_day()
|
||||
|
||||
def is_before(self, target: SolarDay) -> bool:
|
||||
"""
|
||||
是否在指定公历日之前
|
||||
:param target: 公历日
|
||||
:return: true/false
|
||||
"""
|
||||
y: int = target.get_year()
|
||||
if self._year != y:
|
||||
return self._year < y
|
||||
m: int = target.get_month()
|
||||
return self._month < m if self._month != m else self._day < target.get_day()
|
||||
|
||||
def is_after(self, target: SolarDay) -> bool:
|
||||
"""
|
||||
是否在指定公历日之后
|
||||
:param target: 公历日
|
||||
:return: true/false
|
||||
"""
|
||||
y: int = target.get_year()
|
||||
if self._year != y:
|
||||
return self._year > y
|
||||
m: int = target.get_month()
|
||||
return self._month > m if self._month != m else self._day > target.get_day()
|
||||
|
||||
def get_term(self) -> SolarTerm:
|
||||
"""
|
||||
:return: 当天所在的节气 SolarTerm
|
||||
"""
|
||||
return self.get_term_day().get_solar_term()
|
||||
|
||||
def get_term_day(self) -> SolarTermDay:
|
||||
"""
|
||||
:return: 节气第几天
|
||||
"""
|
||||
y: int = self._year
|
||||
i: int = self._month * 2
|
||||
if i == 24:
|
||||
y += 1
|
||||
i = 0
|
||||
term: SolarTerm = SolarTerm(y, i + 1)
|
||||
day: SolarDay = term.get_solar_day()
|
||||
while self.is_before(day):
|
||||
term = term.next(-1)
|
||||
day = term.get_solar_day()
|
||||
return SolarTermDay(term, self.subtract(day))
|
||||
|
||||
def get_solar_week(self, start: int) -> SolarWeek:
|
||||
"""
|
||||
公历周
|
||||
:param start: 起始星期,1234560分别代表星期一至星期天
|
||||
:return: 公历周
|
||||
"""
|
||||
return SolarWeek(self._year, self._month, ceil((self._day + SolarDay(self._year, self._month, 1).get_week().next(-start).get_index()) / 7.0) - 1, start)
|
||||
|
||||
def get_phenology_day(self) -> PhenologyDay:
|
||||
"""
|
||||
当天所在的七十二候
|
||||
:return: 七十二候 PhenologyDay
|
||||
"""
|
||||
d: SolarTermDay = self.get_term_day()
|
||||
day_index: int = d.get_day_index()
|
||||
index: int = day_index // 5
|
||||
if index > 2:
|
||||
index = 2
|
||||
term: SolarTerm = d.get_solar_term()
|
||||
return PhenologyDay(Phenology(term.get_year(), term.get_index() * 3 + index), day_index - index * 5)
|
||||
|
||||
def get_phenology(self) -> Phenology:
|
||||
"""
|
||||
当天所在的候
|
||||
:return: 候 Phenology
|
||||
"""
|
||||
return self.get_phenology_day().get_phenology()
|
||||
|
||||
def get_dog_day(self) -> Union[DogDay, None]:
|
||||
"""
|
||||
当天所在的三伏天
|
||||
:return: 三伏天 DogDay
|
||||
"""
|
||||
# 初伏,夏至后第3个庚日
|
||||
d0: SolarDay = Event.builder().term_heaven_stem(12, 6, 20).build().get_solar_day(self._year)
|
||||
# 中伏,夏至后第4个庚日
|
||||
d1: SolarDay = Event.builder().term_heaven_stem(12, 6, 30).build().get_solar_day(self._year)
|
||||
# 末伏,立秋后第1个庚日
|
||||
d2: SolarDay = Event.builder().term_heaven_stem(15, 6, 0).build().get_solar_day(self._year)
|
||||
if self.is_before(d0) or self.is_after(d2.next(9)):
|
||||
return None
|
||||
if not self.is_before(d2):
|
||||
return DogDay(Dog.from_index(2), self.subtract(d2))
|
||||
return DogDay(Dog.from_index(0), self.subtract(d0)) if self.is_before(d1) else DogDay(Dog.from_index(1), self.subtract(d1))
|
||||
|
||||
def get_plum_rain_day(self) -> Union[PlumRainDay, None]:
|
||||
"""
|
||||
当天所在的梅雨天(芒种后的第1个丙日入梅,小暑后的第1个未日出梅)
|
||||
:return: 梅雨天
|
||||
"""
|
||||
# 入梅,芒种后第1个丙日
|
||||
start: SolarDay = Event.builder().term_heaven_stem(11, 2, 0).build().get_solar_day(self._year)
|
||||
# 出梅,小暑后第1个未日
|
||||
end: SolarDay = Event.builder().term_earth_branch(13, 7, 0).build().get_solar_day(self._year)
|
||||
if self.is_before(start) or self.is_after(end):
|
||||
return None
|
||||
return PlumRainDay(PlumRain(1), 0) if self == end else PlumRainDay(PlumRain(0), self.subtract(start))
|
||||
|
||||
def get_hide_heaven_stem_day(self) -> HideHeavenStemDay:
|
||||
"""
|
||||
:return: 人元司令分野
|
||||
"""
|
||||
from tyme4py.sixtycycle import HideHeavenStemDay, HideHeavenStem
|
||||
day_counts: List[int] = [3, 5, 7, 9, 10, 30]
|
||||
term: SolarTerm = self.get_term()
|
||||
if term.is_qi():
|
||||
term = term.next(-1)
|
||||
day_index: int = self.subtract(term.get_solar_day())
|
||||
start_index: int = (term.get_index() - 1) * 3
|
||||
data: str = '93705542220504xx1513904541632524533533105544806564xx7573304542018584xx95'[start_index: start_index + 6]
|
||||
days: int = 0
|
||||
heaven_stem_index: int = 0
|
||||
type_index: int = 0
|
||||
while type_index < 3:
|
||||
i: int = type_index * 2
|
||||
d: str = data[i: i + 1]
|
||||
count: int = 0
|
||||
if d != 'x':
|
||||
heaven_stem_index = int(d, 10)
|
||||
count = day_counts[int(data[i + 1: i + 2], 10)]
|
||||
days += count
|
||||
|
||||
if day_index <= days:
|
||||
day_index -= days - count
|
||||
break
|
||||
|
||||
type_index += 1
|
||||
|
||||
hide_type: HideHeavenStemType
|
||||
if type_index == 0:
|
||||
hide_type = HideHeavenStemType.RESIDUAL
|
||||
elif type_index == 1:
|
||||
hide_type = HideHeavenStemType.MIDDLE
|
||||
else:
|
||||
hide_type = HideHeavenStemType.MAIN
|
||||
return HideHeavenStemDay(HideHeavenStem(heaven_stem_index, hide_type), day_index)
|
||||
|
||||
def get_nine_day(self) -> Union[NineDay, None]:
|
||||
"""
|
||||
当天所在的数九天
|
||||
:return: 数九天 NineDay
|
||||
"""
|
||||
start: SolarDay = SolarTerm(self._year + 1, 0).get_solar_day()
|
||||
if self.is_before(start):
|
||||
start = SolarTerm(self._year, 0).get_solar_day()
|
||||
|
||||
end: SolarDay = start.next(81)
|
||||
if self.is_before(start) or (not self.is_before(end)):
|
||||
return None
|
||||
|
||||
days: int = self.subtract(start)
|
||||
return NineDay(Nine(int(days / 9)), days % 9)
|
||||
|
||||
def get_index_in_year(self) -> int:
|
||||
"""
|
||||
位于当年的索引
|
||||
:return: 索引
|
||||
"""
|
||||
return self.subtract(SolarDay(self._year, 1, 1))
|
||||
|
||||
def subtract(self, target: SolarDay) -> int:
|
||||
"""
|
||||
公历日期相减,获得相差天数
|
||||
:param target: 公历
|
||||
:return: 两个公历日之间相差的天数
|
||||
"""
|
||||
return int(self.get_julian_day().subtract(target.get_julian_day()))
|
||||
|
||||
def get_julian_day(self) -> JulianDay:
|
||||
"""
|
||||
公历日转儒略日
|
||||
:return: 儒略日
|
||||
"""
|
||||
return JulianDay.from_ymd_hms(self._year, self._month, self._day, 0, 0, 0)
|
||||
|
||||
def get_lunar_day(self) -> LunarDay:
|
||||
"""
|
||||
:return: 农历日
|
||||
"""
|
||||
from tyme4py.lunar import LunarMonth, LunarDay
|
||||
m: LunarMonth = LunarMonth.from_ym(self._year, self._month)
|
||||
days: int = self.subtract(m.get_first_julian_day().get_solar_day())
|
||||
while days < 0:
|
||||
m = m.next(-1)
|
||||
days += m.get_day_count()
|
||||
return LunarDay(m.get_year(), m.get_month_with_leap(), days + 1)
|
||||
|
||||
def get_sixty_cycle_day(self) -> SixtyCycleDay:
|
||||
from tyme4py.sixtycycle import SixtyCycleDay
|
||||
return SixtyCycleDay.from_solar_day(self)
|
||||
|
||||
def get_rab_byung_day(self) -> RabByungDay:
|
||||
from tyme4py.rabbyung import RabByungDay
|
||||
return RabByungDay.from_solar_day(self)
|
||||
|
||||
def get_legal_holiday(self) -> Union[LegalHoliday, None]:
|
||||
"""
|
||||
法定假日,如果当天不是法定假日,返回None
|
||||
:return: 法定假日
|
||||
"""
|
||||
return LegalHoliday.from_ymd(self._year, self._month, self._day)
|
||||
|
||||
def get_festival(self) -> Union[SolarFestival, None]:
|
||||
"""
|
||||
公历现代节日,如果当天不是公历现代节日,返回None
|
||||
:return: 公历现代节日
|
||||
"""
|
||||
return SolarFestival.from_ymd(self._year, self._month, self._day)
|
||||
|
||||
def get_phase_day(self) -> PhaseDay:
|
||||
"""
|
||||
月相第几天
|
||||
:return: 月相第几天
|
||||
"""
|
||||
month = self.get_lunar_day().get_lunar_month().next(1)
|
||||
p = Phase.from_index(month.get_year(), month.get_month_with_leap(), 0)
|
||||
d = p.get_solar_day()
|
||||
while d.is_after(self):
|
||||
p = p.next(-1)
|
||||
d = p.get_solar_day()
|
||||
return PhaseDay(p, self.subtract(d))
|
||||
|
||||
def get_phase(self) -> Phase:
|
||||
"""
|
||||
月相
|
||||
:return: 月相 Phase
|
||||
"""
|
||||
return self.get_phase_day().get_phase()
|
||||
|
||||
def get_nine_star(self) -> NineStar:
|
||||
"""
|
||||
:return: 九星 NineStar
|
||||
"""
|
||||
y: int = self.get_year()
|
||||
winter_solstice: SolarDay = SolarTerm.from_index(y, 0).get_solar_day()
|
||||
summer_solstice: SolarDay = SolarTerm.from_index(y, 12).get_solar_day()
|
||||
next_winter_solstice: SolarDay = SolarTerm.from_index(y + 1, 0).get_solar_day()
|
||||
w: SolarDay = winter_solstice.next(winter_solstice.get_lunar_day().get_sixty_cycle().steps_close_to(0))
|
||||
s: SolarDay = summer_solstice.next(summer_solstice.get_lunar_day().get_sixty_cycle().steps_close_to(0))
|
||||
n: SolarDay = next_winter_solstice.next(next_winter_solstice.get_lunar_day().get_sixty_cycle().steps_close_to(0))
|
||||
if self.is_before(w):
|
||||
return NineStar.from_index(w.subtract(self) - 1)
|
||||
if self.is_before(s):
|
||||
return NineStar.from_index(self.subtract(w))
|
||||
return NineStar.from_index(n.subtract(self) - 1 if self.is_before(n) else self.subtract(n))
|
||||
|
||||
def get_hijri_day(self) -> HijriDay:
|
||||
"""
|
||||
:return: 回历 HijriDay
|
||||
"""
|
||||
d: int = self.subtract(SolarDay(622, 7, 16))
|
||||
z = d // 10631
|
||||
d -= z * 10631
|
||||
y = int(floor((d + 0.5) / 354.366))
|
||||
d -= int(floor(y * 354.366 + 0.5))
|
||||
m = int(floor((d + 0.11) / 29.51))
|
||||
d -= int(floor(m * 29.5 + 0.5))
|
||||
from tyme4py.hijri import HijriDay
|
||||
return HijriDay(z * 30 + y + 1, m + 1, d + 1)
|
||||
|
||||
|
||||
class SolarTime(SecondUnit):
|
||||
|
||||
@staticmethod
|
||||
def validate(year: int, month: int, day: int, hour: int, minute: int, second: int) -> None:
|
||||
SecondUnit.validate(year, month, day, hour, minute, second)
|
||||
SolarDay.validate(year, month, day)
|
||||
|
||||
def __init__(self, year: int, month: int, day: int, hour: int, minute: int, second: int):
|
||||
SolarTime.validate(year, month, day, hour, minute, second)
|
||||
super().__init__(year, month, day, hour, minute, second)
|
||||
|
||||
@classmethod
|
||||
def from_ymd_hms(cls, year: int, month: int, day: int, hour: int, minute: int, second: int) -> SolarTime:
|
||||
"""
|
||||
:param year: 年
|
||||
:param month: 月
|
||||
:param day: 日
|
||||
:param hour: 时
|
||||
:param minute: 分
|
||||
:param second: 秒
|
||||
:return: 公历时刻
|
||||
"""
|
||||
return cls(year, month, day, hour, minute, second)
|
||||
|
||||
def get_solar_day(self) -> SolarDay:
|
||||
"""
|
||||
:return: 公历日
|
||||
"""
|
||||
return SolarDay.from_ymd(self._year, self._month, self._day)
|
||||
|
||||
def get_name(self) -> str:
|
||||
return f'{self._hour:02d}:{self._minute:02d}:{self._second:02d}'
|
||||
|
||||
def __str__(self) -> str:
|
||||
return f'{self.get_solar_day()} {self.get_name()}'
|
||||
|
||||
def next(self, n: int) -> SolarTime:
|
||||
"""
|
||||
推移
|
||||
:param n: 推移秒数
|
||||
:return: 公历时刻
|
||||
"""
|
||||
if n == 0:
|
||||
return SolarTime(self._year, self._month, self._day, self._hour, self._minute, self._second)
|
||||
ts: int = self._second + n
|
||||
tm: int = self._minute + floor(ts / 60)
|
||||
ts %= 60
|
||||
if ts < 0:
|
||||
ts += 60
|
||||
tm -= 1
|
||||
th: int = self._hour + int(tm / 60)
|
||||
tm %= 60
|
||||
if tm < 0:
|
||||
tm += 60
|
||||
th -= 1
|
||||
td: int = int(th / 24)
|
||||
th %= 24
|
||||
if th < 0:
|
||||
th += 24
|
||||
td -= 1
|
||||
d: SolarDay = self.get_solar_day().next(td)
|
||||
return SolarTime(d.get_year(), d.get_month(), d.get_day(), th, tm, ts)
|
||||
|
||||
def is_before(self, target: SolarTime) -> bool:
|
||||
"""
|
||||
是否在指定公历时刻之前
|
||||
:param target: 公历时刻
|
||||
:return: true/false
|
||||
"""
|
||||
a_day: SolarDay = self.get_solar_day()
|
||||
b_day: SolarDay = target.get_solar_day()
|
||||
if a_day != b_day:
|
||||
return a_day.is_before(b_day)
|
||||
h: int = target.get_hour()
|
||||
if self._hour != h:
|
||||
return self._hour < h
|
||||
m: int = target.get_minute()
|
||||
return self._minute < m if self._minute != m else self._second < target.get_second()
|
||||
|
||||
def is_after(self, target: SolarTime) -> bool:
|
||||
"""
|
||||
是否在指定公历时刻之后
|
||||
:param target: 公历时刻
|
||||
:return: true/false
|
||||
"""
|
||||
a_day: SolarDay = self.get_solar_day()
|
||||
b_day: SolarDay = target.get_solar_day()
|
||||
if a_day != b_day:
|
||||
return a_day.is_after(b_day)
|
||||
h: int = target.get_hour()
|
||||
if self._hour != h:
|
||||
return self._hour > h
|
||||
m: int = target.get_minute()
|
||||
return self._minute > m if self._minute != m else self._second > target.get_second()
|
||||
|
||||
def get_term(self) -> SolarTerm:
|
||||
"""
|
||||
当时所在的节气
|
||||
:return: 节气 SolarTerm
|
||||
"""
|
||||
term: SolarTerm = self.get_solar_day().get_term()
|
||||
if self.is_before(term.get_julian_day().get_solar_time()):
|
||||
term = term.next(-1)
|
||||
return term
|
||||
|
||||
def get_phenology(self) -> Phenology:
|
||||
"""
|
||||
当时所在的候
|
||||
:return: 候 Phenology
|
||||
"""
|
||||
p: Phenology = self.get_solar_day().get_phenology()
|
||||
if self.is_before(p.get_julian_day().get_solar_time()):
|
||||
p = p.next(-1)
|
||||
return p
|
||||
|
||||
def get_julian_day(self) -> JulianDay:
|
||||
"""
|
||||
公历时刻转儒略日
|
||||
:return: 儒略日
|
||||
"""
|
||||
return JulianDay.from_ymd_hms(self._year, self._month, self._day, self._hour, self._minute, self._second)
|
||||
|
||||
def subtract(self, target: SolarTime) -> int:
|
||||
"""
|
||||
公历时刻相减,获得相差秒数
|
||||
:param target: 公历时刻
|
||||
:return: 秒数
|
||||
"""
|
||||
days: int = self.get_solar_day().subtract(target.get_solar_day())
|
||||
cs: int = self._hour * 3600 + self._minute * 60 + self._second
|
||||
ts: int = target.get_hour() * 3600 + target.get_minute() * 60 + target.get_second()
|
||||
seconds: int = cs - ts
|
||||
if seconds < 0:
|
||||
seconds += 86400
|
||||
days -= 1
|
||||
seconds += days * 86400
|
||||
return seconds
|
||||
|
||||
def get_lunar_hour(self) -> LunarHour:
|
||||
"""
|
||||
农历时辰
|
||||
:return: 农历时辰
|
||||
"""
|
||||
from tyme4py.lunar import LunarDay, LunarHour
|
||||
d: LunarDay = self.get_solar_day().get_lunar_day()
|
||||
return LunarHour(d.get_year(), d.get_month(), d.get_day(), self._hour, self._minute, self._second)
|
||||
|
||||
def get_sixty_cycle_hour(self) -> SixtyCycleHour:
|
||||
"""
|
||||
干支时辰
|
||||
:return: 干支时辰
|
||||
"""
|
||||
from tyme4py.sixtycycle import SixtyCycleHour
|
||||
return SixtyCycleHour.from_solar_time(self)
|
||||
|
||||
def get_phase(self) -> Phase:
|
||||
"""
|
||||
月相
|
||||
:return: 月相 Phase
|
||||
"""
|
||||
month = self.get_lunar_hour().get_lunar_day().get_lunar_month().next(1)
|
||||
p = Phase.from_index(month.get_year(), month.get_month_with_leap(), 0)
|
||||
while p.get_solar_time().is_after(self):
|
||||
p = p.next(-1)
|
||||
return p
|
||||
Vendored
+92
@@ -0,0 +1,92 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
from __future__ import annotations
|
||||
|
||||
from abc import ABC
|
||||
from typing import List
|
||||
|
||||
from tyme4py import AbstractTyme
|
||||
|
||||
|
||||
class YearUnit(AbstractTyme, ABC):
|
||||
"""年"""
|
||||
|
||||
def __init__(self, year: int):
|
||||
self._year = year
|
||||
|
||||
def get_year(self) -> int:
|
||||
return self._year
|
||||
|
||||
|
||||
class MonthUnit(YearUnit, ABC):
|
||||
"""月"""
|
||||
|
||||
def __init__(self, year: int, month: int):
|
||||
super().__init__(year)
|
||||
self._month = month
|
||||
|
||||
def get_month(self) -> int:
|
||||
return self._month
|
||||
|
||||
|
||||
class DayUnit(MonthUnit, ABC):
|
||||
"""日"""
|
||||
|
||||
def __init__(self, year: int, month: int, day: int):
|
||||
super().__init__(year, month)
|
||||
self._day = day
|
||||
|
||||
def get_day(self) -> int:
|
||||
return self._day
|
||||
|
||||
|
||||
class SecondUnit(DayUnit, ABC):
|
||||
"""秒"""
|
||||
|
||||
def __init__(self, year: int, month: int, day: int, hour: int, minute: int, second: int):
|
||||
super().__init__(year, month, day)
|
||||
self._hour = hour
|
||||
self._minute = minute
|
||||
self._second = second
|
||||
|
||||
def get_hour(self) -> int:
|
||||
return self._hour
|
||||
|
||||
def get_minute(self) -> int:
|
||||
return self._minute
|
||||
|
||||
def get_second(self) -> int:
|
||||
return self._second
|
||||
|
||||
@staticmethod
|
||||
def validate(year: int, month: int, day: int, hour: int, minute: int, second: int) -> None:
|
||||
if hour < 0 or hour > 23:
|
||||
raise ValueError(f'illegal hour: {hour}')
|
||||
if minute < 0 or minute > 59:
|
||||
raise ValueError(f'illegal minute: {minute}')
|
||||
if second < 0 or second > 59:
|
||||
raise ValueError(f'illegal second: {second}')
|
||||
|
||||
|
||||
class WeekUnit(MonthUnit, ABC):
|
||||
"""周"""
|
||||
|
||||
NAMES: List[str] = ['第一周', '第二周', '第三周', '第四周', '第五周', '第六周']
|
||||
"""名称"""
|
||||
|
||||
def __init__(self, year: int, month: int, index: int, start: int):
|
||||
super().__init__(year, month)
|
||||
self._index = index
|
||||
self._start = start
|
||||
|
||||
def get_index(self) -> int:
|
||||
return self._index
|
||||
|
||||
def get_start(self) -> int:
|
||||
return self._start
|
||||
|
||||
@staticmethod
|
||||
def validate(year: int, month: int, index: int, start: int) -> None:
|
||||
if index < 0 or index > 5:
|
||||
raise ValueError(f'illegal week index: {index}')
|
||||
if start < 0 or start > 6:
|
||||
raise ValueError(f'illegal week start: {start}')
|
||||
Vendored
+842
@@ -0,0 +1,842 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
from math import floor, cos, sin
|
||||
|
||||
|
||||
class ShouXingUtil:
|
||||
# 2000年儒略日数(2000-1-1 12:00:00 UTC)
|
||||
J2000 = 2451545
|
||||
PI: float = 3.141592653589793
|
||||
PI_2: float = 2 * PI
|
||||
ONE_THIRD: float = 1.0 / 3
|
||||
# 1天对应的秒数
|
||||
SECOND_PER_DAY: int = 86400
|
||||
# 1弧度对应的角秒
|
||||
SECOND_PER_RAD: float = 648000 / PI
|
||||
# 中精度章动计算表
|
||||
__NUT_B = (
|
||||
2.1824, -33.75705, 36e-6, -1720, 920,
|
||||
3.5069, 1256.66393, 11e-6, -132, 57,
|
||||
1.3375, 16799.4182, -51e-6, -23, 10,
|
||||
4.3649, -67.5141, 72e-6, 21, -9,
|
||||
0.04, -628.302, 0, -14, 0,
|
||||
2.36, 8328.691, 0, 7, 0,
|
||||
3.46, 1884.966, 0, -5, 2,
|
||||
5.44, 16833.175, 0, -4, 2,
|
||||
3.69, 25128.110, 0, -3, 0,
|
||||
3.55, 628.362, 0, 2, 0
|
||||
)
|
||||
# TD - UT1 计算表
|
||||
__DT_AT = (
|
||||
-4000, 108371.7, -13036.80, 392.000, 0.0000,
|
||||
-500, 17201.0, -627.82, 16.170, -0.3413,
|
||||
-150, 12200.6, -346.41, 5.403, -0.1593,
|
||||
150, 9113.8, -328.13, -1.647, 0.0377,
|
||||
500, 5707.5, -391.41, 0.915, 0.3145,
|
||||
900, 2203.4, -283.45, 13.034, -0.1778,
|
||||
1300, 490.1, -57.35, 2.085, -0.0072,
|
||||
1600, 120.0, -9.81, -1.532, 0.1403,
|
||||
1700, 10.2, -0.91, 0.510, -0.0370,
|
||||
1800, 13.4, -0.72, 0.202, -0.0193,
|
||||
1830, 7.8, -1.81, 0.416, -0.0247,
|
||||
1860, 8.3, -0.13, -0.406, 0.0292,
|
||||
1880, -5.4, 0.32, -0.183, 0.0173,
|
||||
1900, -2.3, 2.06, 0.169, -0.0135,
|
||||
1920, 21.2, 1.69, -0.304, 0.0167,
|
||||
1940, 24.2, 1.22, -0.064, 0.0031,
|
||||
1960, 33.2, 0.51, 0.231, -0.0109,
|
||||
1980, 51.0, 1.29, -0.026, 0.0032,
|
||||
2000, 63.87, 0.1, 0, 0,
|
||||
2005, 64.7, 0.21, 0, 0,
|
||||
2012, 66.8, 0.22, 0, 0,
|
||||
2016, 68.1024, 0.5456, -0.0542, -0.001172,
|
||||
2020, 69.3612, 0.0422, -0.0502, 0.006216,
|
||||
2024, 69.1752, -0.0335, -0.0048, 0.000811,
|
||||
2028, 69.0206, -0.0275, 0.0055, -0.000014,
|
||||
2032, 68.9981, 0.0163, 0.0054, 0.000006,
|
||||
2036, 69.1498, 0.0599, 0.0053, 0.000026,
|
||||
2040, 69.4751, 0.1035, 0.0051, 0.000046,
|
||||
2044, 69.9737, 0.1469, 0.0050, 0.000066,
|
||||
2048, 70.6451, 0.1903, 0.0049, 0.000085,
|
||||
2050, 71.0457
|
||||
)
|
||||
__XL0 = (
|
||||
10000000000,
|
||||
20, 578, 920, 1100, 1124, 1136, 1148, 1217, 1226, 1229, 1229, 1229, 1229, 1937, 2363, 2618, 2633, 2660, 2666,
|
||||
17534704567, 0.00000000000, 0.00000000000, 334165646, 4.669256804, 6283.075849991, 3489428, 4.6261024,
|
||||
12566.1517000, 349706, 2.744118, 5753.384885, 341757, 2.828866, 3.523118, 313590, 3.627670, 77713.771468,
|
||||
267622, 4.418084, 7860.419392, 234269, 6.135162, 3930.209696, 132429, 0.742464, 11506.769770, 127317, 2.037097,
|
||||
529.690965, 119917, 1.109629, 1577.343542, 99025, 5.23268, 5884.92685, 90186, 2.04505, 26.29832, 85722, 3.50849,
|
||||
398.14900, 77979, 1.17883, 5223.69392, 75314, 2.53339, 5507.55324, 50526, 4.58293, 18849.22755, 49238, 4.20507,
|
||||
775.52261, 35666, 2.91954, 0.06731, 31709, 5.84902, 11790.62909, 28413, 1.89869, 796.29801, 27104, 0.31489,
|
||||
10977.07880, 24281, 0.34481, 5486.77784, 20616, 4.80647, 2544.31442, 20539, 1.86948, 5573.14280, 20226, 2.45768,
|
||||
6069.77675, 15552, 0.83306, 213.29910, 13221, 3.41118, 2942.46342, 12618, 1.08303, 20.77540, 11513, 0.64545,
|
||||
0.98032, 10285, 0.63600, 4694.00295, 10190, 0.97569, 15720.83878, 10172, 4.26680, 7.11355, 9921, 6.2099,
|
||||
2146.1654, 9761, 0.6810, 155.4204, 8580, 5.9832, 161000.6857, 8513, 1.2987, 6275.9623, 8471, 3.6708, 71430.6956,
|
||||
7964, 1.8079, 17260.1547, 7876, 3.0370, 12036.4607, 7465, 1.7551, 5088.6288, 7387, 3.5032, 3154.6871, 7355,
|
||||
4.6793, 801.8209, 6963, 0.8330, 9437.7629, 6245, 3.9776, 8827.3903, 6115, 1.8184, 7084.8968, 5696, 2.7843,
|
||||
6286.5990, 5612, 4.3869, 14143.4952, 5558, 3.4701, 6279.5527, 5199, 0.1891, 12139.5535, 5161, 1.3328, 1748.0164,
|
||||
5115, 0.2831, 5856.4777, 4900, 0.4874, 1194.4470, 4104, 5.3682, 8429.2413, 4094, 2.3985, 19651.0485, 3920,
|
||||
6.1683, 10447.3878, 3677, 6.0413, 10213.2855, 3660, 2.5696, 1059.3819, 3595, 1.7088, 2352.8662, 3557, 1.7760,
|
||||
6812.7668, 3329, 0.5931, 17789.8456, 3041, 0.4429, 83996.8473, 3005, 2.7398, 1349.8674, 2535, 3.1647, 4690.4798,
|
||||
2474, 0.2148, 3.5904, 2366, 0.4847, 8031.0923, 2357, 2.0653, 3340.6124, 2282, 5.2220, 4705.7323, 2189, 5.5559,
|
||||
553.5694, 2142, 1.4256, 16730.4637, 2109, 4.1483, 951.7184, 2030, 0.3713, 283.8593, 1992, 5.2221, 12168.0027,
|
||||
1986, 5.7747, 6309.3742, 1912, 3.8222, 23581.2582, 1889, 5.3863, 149854.4001, 1790, 2.2149, 13367.9726, 1748,
|
||||
4.5605, 135.0651, 1622, 5.9884, 11769.8537, 1508, 4.1957, 6256.7775, 1442, 4.1932, 242.7286, 1435, 3.7236,
|
||||
38.0277, 1397, 4.4014, 6681.2249, 1362, 1.8893, 7632.9433, 1250, 1.1305, 5.5229, 1205, 2.6223, 955.5997, 1200,
|
||||
1.0035, 632.7837, 1129, 0.1774, 4164.3120, 1083, 0.3273, 103.0928, 1052, 0.9387, 11926.2544, 1050, 5.3591,
|
||||
1592.5960, 1033, 6.1998, 6438.4962, 1001, 6.0291, 5746.2713, 980, 0.999, 11371.705, 980, 5.244, 27511.468, 938,
|
||||
2.624, 5760.498, 923, 0.483, 522.577, 922, 4.571, 4292.331, 905, 5.337, 6386.169, 862, 4.165, 7058.598, 841,
|
||||
3.299, 7234.794, 836, 4.539, 25132.303, 813, 6.112, 4732.031, 812, 6.271, 426.598, 801, 5.821, 28.449, 787,
|
||||
0.996, 5643.179, 776, 2.957, 23013.540, 769, 3.121, 7238.676, 758, 3.974, 11499.656, 735, 4.386, 316.392, 731,
|
||||
0.607, 11513.883, 719, 3.998, 74.782, 706, 0.323, 263.084, 676, 5.911, 90955.552, 663, 3.665, 17298.182, 653,
|
||||
5.791, 18073.705, 630, 4.717, 6836.645, 615, 1.458, 233141.314, 612, 1.075, 19804.827, 596, 3.321, 6283.009,
|
||||
596, 2.876, 6283.143, 555, 2.452, 12352.853, 541, 5.392, 419.485, 531, 0.382, 31441.678, 519, 4.065, 6208.294,
|
||||
513, 2.361, 10973.556, 494, 5.737, 9917.697, 450, 3.272, 11015.106, 449, 3.653, 206.186, 447, 2.064, 7079.374,
|
||||
435, 4.423, 5216.580, 421, 1.906, 245.832, 413, 0.921, 3738.761, 402, 0.840, 20.355, 387, 1.826, 11856.219, 379,
|
||||
2.344, 3.881, 374, 2.954, 3128.389, 370, 5.031, 536.805, 365, 1.018, 16200.773, 365, 1.083, 88860.057, 352,
|
||||
5.978, 3894.182, 352, 2.056, 244287.600, 351, 3.713, 6290.189, 340, 1.106, 14712.317, 339, 0.978, 8635.942, 339,
|
||||
3.202, 5120.601, 333, 0.837, 6496.375, 325, 3.479, 6133.513, 316, 5.089, 21228.392, 316, 1.328, 10873.986, 309,
|
||||
3.646, 10.637, 303, 1.802, 35371.887, 296, 3.397, 9225.539, 288, 6.026, 154717.610, 281, 2.585, 14314.168, 262,
|
||||
3.856, 266.607, 262, 2.579, 22483.849, 257, 1.561, 23543.231, 255, 3.949, 1990.745, 251, 3.744, 10575.407, 240,
|
||||
1.161, 10984.192, 238, 0.106, 7.046, 236, 4.272, 6040.347, 234, 3.577, 10969.965, 211, 3.714, 65147.620, 210,
|
||||
0.754, 13521.751, 207, 4.228, 5650.292, 202, 0.814, 170.673, 201, 4.629, 6037.244, 200, 0.381, 6172.870, 199,
|
||||
3.933, 6206.810, 199, 5.197, 6262.300, 197, 1.046, 18209.330, 195, 1.070, 5230.807, 195, 4.869, 36.028, 194,
|
||||
4.313, 6244.943, 192, 1.229, 709.933, 192, 5.595, 6282.096, 192, 0.602, 6284.056, 189, 3.744, 23.878, 188,
|
||||
1.904, 15.252, 188, 0.867, 22003.915, 182, 3.681, 15110.466, 181, 0.491, 1.484, 179, 3.222, 39302.097, 179,
|
||||
1.259, 12559.038,
|
||||
62833196674749, 0.000000000000, 0.000000000000, 20605886, 2.67823456, 6283.07584999, 430343, 2.635127,
|
||||
12566.151700, 42526, 1.59047, 3.52312, 11926, 5.79557, 26.29832, 10898, 2.96618, 1577.34354, 9348, 2.5921,
|
||||
18849.2275, 7212, 1.1385, 529.6910, 6777, 1.8747, 398.1490, 6733, 4.4092, 5507.5532, 5903, 2.8880, 5223.6939,
|
||||
5598, 2.1747, 155.4204, 4541, 0.3980, 796.2980, 3637, 0.4662, 775.5226, 2896, 2.6471, 7.1135, 2084, 5.3414,
|
||||
0.9803, 1910, 1.8463, 5486.7778, 1851, 4.9686, 213.2991, 1729, 2.9912, 6275.9623, 1623, 0.0322, 2544.3144, 1583,
|
||||
1.4305, 2146.1654, 1462, 1.2053, 10977.0788, 1246, 2.8343, 1748.0164, 1188, 3.2580, 5088.6288, 1181, 5.2738,
|
||||
1194.4470, 1151, 2.0750, 4694.0030, 1064, 0.7661, 553.5694, 997, 1.303, 6286.599, 972, 4.239, 1349.867, 945,
|
||||
2.700, 242.729, 858, 5.645, 951.718, 758, 5.301, 2352.866, 639, 2.650, 9437.763, 610, 4.666, 4690.480, 583,
|
||||
1.766, 1059.382, 531, 0.909, 3154.687, 522, 5.661, 71430.696, 520, 1.854, 801.821, 504, 1.425, 6438.496, 433,
|
||||
0.241, 6812.767, 426, 0.774, 10447.388, 413, 5.240, 7084.897, 374, 2.001, 8031.092, 356, 2.429, 14143.495, 350,
|
||||
4.800, 6279.553, 337, 0.888, 12036.461, 337, 3.862, 1592.596, 325, 3.400, 7632.943, 322, 0.616, 8429.241, 318,
|
||||
3.188, 4705.732, 297, 6.070, 4292.331, 295, 1.431, 5746.271, 290, 2.325, 20.355, 275, 0.935, 5760.498, 270,
|
||||
4.804, 7234.794, 253, 6.223, 6836.645, 228, 5.003, 17789.846, 225, 5.672, 11499.656, 215, 5.202, 11513.883, 208,
|
||||
3.955, 10213.286, 208, 2.268, 522.577, 206, 2.224, 5856.478, 206, 2.550, 25132.303, 203, 0.910, 6256.778, 189,
|
||||
0.532, 3340.612, 188, 4.735, 83996.847, 179, 1.474, 4164.312, 178, 3.025, 5.523, 177, 3.026, 5753.385, 159,
|
||||
4.637, 3.286, 157, 6.124, 5216.580, 155, 3.077, 6681.225, 154, 4.200, 13367.973, 143, 1.191, 3894.182, 138,
|
||||
3.093, 135.065, 136, 4.245, 426.598, 134, 5.765, 6040.347, 128, 3.085, 5643.179, 127, 2.092, 6290.189, 125,
|
||||
3.077, 11926.254, 125, 3.445, 536.805, 114, 3.244, 12168.003, 112, 2.318, 16730.464, 111, 3.901, 11506.770, 111,
|
||||
5.320, 23.878, 105, 3.750, 7860.419, 103, 2.447, 1990.745, 96, 0.82, 3.88, 96, 4.08, 6127.66, 91, 5.42, 206.19,
|
||||
91, 0.42, 7079.37, 88, 5.17, 11790.63, 81, 0.34, 9917.70, 80, 3.89, 10973.56, 78, 2.40, 1589.07, 78, 2.58,
|
||||
11371.70, 77, 3.98, 955.60, 77, 3.36, 36.03, 76, 1.30, 103.09, 75, 5.18, 10969.97, 75, 4.96, 6496.37, 73, 5.21,
|
||||
38.03, 72, 2.65, 6309.37, 70, 5.61, 3738.76, 69, 2.60, 3496.03, 69, 0.39, 15.25, 69, 2.78, 20.78, 65, 1.13,
|
||||
7058.60, 64, 4.28, 28.45, 61, 5.63, 10984.19, 60, 0.73, 419.48, 60, 5.28, 10575.41, 58, 5.55, 17298.18, 58,
|
||||
3.19, 4732.03,
|
||||
5291887, 0.0000000, 0.0000000, 871984, 1.072097, 6283.075850, 30913, 0.86729, 12566.15170, 2734, 0.0530, 3.5231,
|
||||
1633, 5.1883, 26.2983, 1575, 3.6846, 155.4204, 954, 0.757, 18849.228, 894, 2.057, 77713.771, 695, 0.827,
|
||||
775.523, 506, 4.663, 1577.344, 406, 1.031, 7.114, 381, 3.441, 5573.143, 346, 5.141, 796.298, 317, 6.053,
|
||||
5507.553, 302, 1.192, 242.729, 289, 6.117, 529.691, 271, 0.306, 398.149, 254, 2.280, 553.569, 237, 4.381,
|
||||
5223.694, 208, 3.754, 0.980, 168, 0.902, 951.718, 153, 5.759, 1349.867, 145, 4.364, 1748.016, 134, 3.721,
|
||||
1194.447, 125, 2.948, 6438.496, 122, 2.973, 2146.165, 110, 1.271, 161000.686, 104, 0.604, 3154.687, 100, 5.986,
|
||||
6286.599, 92, 4.80, 5088.63, 89, 5.23, 7084.90, 83, 3.31, 213.30, 76, 3.42, 5486.78, 71, 6.19, 4690.48, 68,
|
||||
3.43, 4694.00, 65, 1.60, 2544.31, 64, 1.98, 801.82, 61, 2.48, 10977.08, 50, 1.44, 6836.65, 49, 2.34, 1592.60,
|
||||
46, 1.31, 4292.33, 46, 3.81, 149854.40, 43, 0.04, 7234.79, 40, 4.94, 7632.94, 39, 1.57, 71430.70, 38, 3.17,
|
||||
6309.37, 35, 0.99, 6040.35, 35, 0.67, 1059.38, 31, 3.18, 2352.87, 31, 3.55, 8031.09, 30, 1.92, 10447.39, 30,
|
||||
2.52, 6127.66, 28, 4.42, 9437.76, 28, 2.71, 3894.18, 27, 0.67, 25132.30, 26, 5.27, 6812.77, 25, 0.55, 6279.55,
|
||||
23, 1.38, 4705.73, 22, 0.64, 6256.78, 20, 6.07, 640.88,
|
||||
28923, 5.84384, 6283.07585, 3496, 0.0000, 0.0000, 1682, 5.4877, 12566.1517, 296, 5.196, 155.420, 129, 4.722,
|
||||
3.523, 71, 5.30, 18849.23, 64, 5.97, 242.73, 40, 3.79, 553.57,
|
||||
11408, 3.14159, 0.00000, 772, 4.134, 6283.076, 77, 3.84, 12566.15, 42, 0.42, 155.42,
|
||||
88, 3.14, 0.00, 17, 2.77, 6283.08, 5, 2.01, 155.42, 3, 2.21, 12566.15,
|
||||
27962, 3.19870, 84334.66158, 10164, 5.42249, 5507.55324, 8045, 3.8801, 5223.6939, 4381, 3.7044, 2352.8662, 3193,
|
||||
4.0003, 1577.3435, 2272, 3.9847, 1047.7473, 1814, 4.9837, 6283.0758, 1639, 3.5646, 5856.4777, 1444, 3.7028,
|
||||
9437.7629, 1430, 3.4112, 10213.2855, 1125, 4.8282, 14143.4952, 1090, 2.0857, 6812.7668, 1037, 4.0566,
|
||||
71092.8814, 971, 3.473, 4694.003, 915, 1.142, 6620.890, 878, 4.440, 5753.385, 837, 4.993, 7084.897, 770, 5.554,
|
||||
167621.576, 719, 3.602, 529.691, 692, 4.326, 6275.962, 558, 4.410, 7860.419, 529, 2.484, 4705.732, 521, 6.250,
|
||||
18073.705,
|
||||
903, 3.897, 5507.553, 618, 1.730, 5223.694, 380, 5.244, 2352.866,
|
||||
166, 1.627, 84334.662,
|
||||
10001398880, 0.00000000000, 0.00000000000, 167069963, 3.098463508, 6283.075849991, 1395602, 3.0552461,
|
||||
12566.1517000, 308372, 5.198467, 77713.771468, 162846, 1.173877, 5753.384885, 157557, 2.846852, 7860.419392,
|
||||
92480, 5.45292, 11506.76977, 54244, 4.56409, 3930.20970, 47211, 3.66100, 5884.92685, 34598, 0.96369, 5507.55324,
|
||||
32878, 5.89984, 5223.69392, 30678, 0.29867, 5573.14280, 24319, 4.27350, 11790.62909, 21183, 5.84715, 1577.34354,
|
||||
18575, 5.02194, 10977.07880, 17484, 3.01194, 18849.22755, 10984, 5.05511, 5486.77784, 9832, 0.8868, 6069.7768,
|
||||
8650, 5.6896, 15720.8388, 8583, 1.2708, 161000.6857, 6490, 0.2725, 17260.1547, 6292, 0.9218, 529.6910, 5706,
|
||||
2.0137, 83996.8473, 5574, 5.2416, 71430.6956, 4938, 3.2450, 2544.3144, 4696, 2.5781, 775.5226, 4466, 5.5372,
|
||||
9437.7629, 4252, 6.0111, 6275.9623, 3897, 5.3607, 4694.0030, 3825, 2.3926, 8827.3903, 3749, 0.8295, 19651.0485,
|
||||
3696, 4.9011, 12139.5535, 3566, 1.6747, 12036.4607, 3454, 1.8427, 2942.4634, 3319, 0.2437, 7084.8968, 3192,
|
||||
0.1837, 5088.6288, 3185, 1.7778, 398.1490, 2846, 1.2134, 6286.5990, 2779, 1.8993, 6279.5527, 2628, 4.5890,
|
||||
10447.3878, 2460, 3.7866, 8429.2413, 2393, 4.9960, 5856.4777, 2359, 0.2687, 796.2980, 2329, 2.8078, 14143.4952,
|
||||
2210, 1.9500, 3154.6871, 2035, 4.6527, 2146.1654, 1951, 5.3823, 2352.8662, 1883, 0.6731, 149854.4001, 1833,
|
||||
2.2535, 23581.2582, 1796, 0.1987, 6812.7668, 1731, 6.1520, 16730.4637, 1717, 4.4332, 10213.2855, 1619, 5.2316,
|
||||
17789.8456, 1381, 5.1896, 8031.0923, 1364, 3.6852, 4705.7323, 1314, 0.6529, 13367.9726, 1041, 4.3329,
|
||||
11769.8537, 1017, 1.5939, 4690.4798, 998, 4.201, 6309.374, 966, 3.676, 27511.468, 874, 6.064, 1748.016, 779,
|
||||
3.674, 12168.003, 771, 0.312, 7632.943, 756, 2.626, 6256.778, 746, 5.648, 11926.254, 693, 2.924, 6681.225, 680,
|
||||
1.423, 23013.540, 674, 0.563, 3340.612, 663, 5.661, 11371.705, 659, 3.136, 801.821, 648, 2.650, 19804.827, 615,
|
||||
3.029, 233141.314, 612, 5.134, 1194.447, 563, 4.341, 90955.552, 552, 2.091, 17298.182, 534, 5.100, 31441.678,
|
||||
531, 2.407, 11499.656, 523, 4.624, 6438.496, 513, 5.324, 11513.883, 477, 0.256, 11856.219, 461, 1.722, 7234.794,
|
||||
458, 3.766, 6386.169, 458, 4.466, 5746.271, 423, 1.055, 5760.498, 422, 1.557, 7238.676, 415, 2.599, 7058.598,
|
||||
401, 3.030, 1059.382, 397, 1.201, 1349.867, 379, 4.907, 4164.312, 360, 5.707, 5643.179, 352, 3.626, 244287.600,
|
||||
348, 0.761, 10973.556, 342, 3.001, 4292.331, 336, 4.546, 4732.031, 334, 3.138, 6836.645, 324, 4.164, 9917.697,
|
||||
316, 1.691, 11015.106, 307, 0.238, 35371.887, 298, 1.306, 6283.143, 298, 1.750, 6283.009, 293, 5.738, 16200.773,
|
||||
286, 5.928, 14712.317, 281, 3.515, 21228.392, 280, 5.663, 8635.942, 277, 0.513, 26.298, 268, 4.207, 18073.705,
|
||||
266, 0.900, 12352.853, 260, 2.962, 25132.303, 255, 2.477, 6208.294, 242, 2.800, 709.933, 231, 1.054, 22483.849,
|
||||
229, 1.070, 14314.168, 216, 1.314, 154717.610, 215, 6.038, 10873.986, 200, 0.561, 7079.374, 198, 2.614, 951.718,
|
||||
197, 4.369, 167283.762, 186, 2.861, 5216.580, 183, 1.660, 39302.097, 183, 5.912, 3738.761, 175, 2.145, 6290.189,
|
||||
173, 2.168, 10575.407, 171, 3.702, 1592.596, 171, 1.343, 3128.389, 164, 5.550, 6496.375, 164, 5.856, 10984.192,
|
||||
161, 1.998, 10969.965, 161, 1.909, 6133.513, 157, 4.955, 25158.602, 154, 6.216, 23543.231, 153, 5.357,
|
||||
13521.751, 150, 5.770, 18209.330, 150, 5.439, 155.420, 139, 1.778, 9225.539, 139, 1.626, 5120.601, 128, 2.460,
|
||||
13916.019, 123, 0.717, 143571.324, 122, 2.654, 88860.057, 121, 4.414, 3894.182, 121, 1.192, 3.523, 120, 4.030,
|
||||
553.569, 119, 1.513, 17654.781, 117, 3.117, 14945.316, 113, 2.698, 6040.347, 110, 3.085, 43232.307, 109, 0.998,
|
||||
955.600, 108, 2.939, 17256.632, 107, 5.285, 65147.620, 103, 0.139, 11712.955, 103, 5.850, 213.299, 102, 3.046,
|
||||
6037.244, 101, 2.842, 8662.240, 100, 3.626, 6262.300, 98, 2.36, 6206.81, 98, 5.11, 6172.87, 98, 2.00, 15110.47,
|
||||
97, 2.67, 5650.29, 97, 2.75, 6244.94, 96, 4.02, 6282.10, 96, 5.31, 6284.06, 92, 0.10, 29088.81, 85, 3.26,
|
||||
20426.57, 84, 2.60, 28766.92, 81, 3.58, 10177.26, 80, 5.81, 5230.81, 78, 2.53, 16496.36, 77, 4.06, 6127.66, 73,
|
||||
0.04, 5481.25, 72, 5.96, 12559.04, 72, 5.92, 4136.91, 71, 5.49, 22003.91, 70, 3.41, 7.11, 69, 0.62, 11403.68,
|
||||
69, 3.90, 1589.07, 69, 1.96, 12416.59, 69, 4.51, 426.60, 67, 1.61, 11087.29, 66, 4.50, 47162.52, 66, 5.08,
|
||||
283.86, 66, 4.32, 16858.48, 65, 1.04, 6062.66, 64, 1.59, 18319.54, 63, 5.70, 45892.73, 63, 4.60, 66567.49, 63,
|
||||
3.82, 13517.87, 62, 2.62, 11190.38, 61, 1.54, 33019.02, 60, 5.58, 10344.30, 60, 5.38, 316428.23, 60, 5.78,
|
||||
632.78, 59, 6.12, 9623.69, 57, 0.16, 17267.27, 57, 3.86, 6076.89, 57, 1.98, 7668.64, 56, 4.78, 20199.09, 55,
|
||||
4.56, 18875.53, 55, 3.51, 17253.04, 54, 3.07, 226858.24, 54, 4.83, 18422.63, 53, 5.02, 12132.44, 52, 3.63,
|
||||
5333.90, 52, 0.97, 155427.54, 51, 3.36, 20597.24, 50, 0.99, 11609.86, 50, 2.21, 1990.75, 48, 1.62, 12146.67, 48,
|
||||
1.17, 12569.67, 47, 4.62, 5436.99, 47, 1.81, 12562.63, 47, 0.59, 21954.16, 47, 0.76, 7342.46, 46, 0.27, 4590.91,
|
||||
46, 3.77, 156137.48, 45, 5.66, 10454.50, 44, 5.84, 3496.03, 43, 0.24, 17996.03, 41, 5.93, 51092.73, 41, 4.21,
|
||||
12592.45, 40, 5.14, 1551.05, 40, 5.28, 15671.08, 39, 3.69, 18052.93, 39, 4.94, 24356.78, 38, 2.72, 11933.37, 38,
|
||||
5.23, 7477.52, 38, 4.99, 9779.11, 37, 3.70, 9388.01, 37, 4.44, 4535.06, 36, 2.16, 28237.23, 36, 2.54, 242.73,
|
||||
36, 0.22, 5429.88, 35, 6.15, 19800.95, 35, 2.92, 36949.23, 34, 5.63, 2379.16, 34, 5.73, 16460.33, 34, 5.11,
|
||||
5849.36, 33, 6.19, 6268.85,
|
||||
10301861, 1.10748970, 6283.07584999, 172124, 1.064423, 12566.151700, 70222, 3.14159, 0.00000, 3235, 1.0217,
|
||||
18849.2275, 3080, 2.8435, 5507.5532, 2497, 1.3191, 5223.6939, 1849, 1.4243, 1577.3435, 1008, 5.9138, 10977.0788,
|
||||
865, 1.420, 6275.962, 863, 0.271, 5486.778, 507, 1.686, 5088.629, 499, 6.014, 6286.599, 467, 5.987, 529.691,
|
||||
440, 0.518, 4694.003, 410, 1.084, 9437.763, 387, 4.750, 2544.314, 375, 5.071, 796.298, 352, 0.023, 83996.847,
|
||||
344, 0.949, 71430.696, 341, 5.412, 775.523, 322, 6.156, 2146.165, 286, 5.484, 10447.388, 284, 3.420, 2352.866,
|
||||
255, 6.132, 6438.496, 252, 0.243, 398.149, 243, 3.092, 4690.480, 225, 3.689, 7084.897, 220, 4.952, 6812.767,
|
||||
219, 0.420, 8031.092, 209, 1.282, 1748.016, 193, 5.314, 8429.241, 185, 1.820, 7632.943, 175, 3.229, 6279.553,
|
||||
173, 1.537, 4705.732, 158, 4.097, 11499.656, 158, 5.539, 3154.687, 150, 3.633, 11513.883, 148, 3.222, 7234.794,
|
||||
147, 3.653, 1194.447, 144, 0.817, 14143.495, 135, 6.151, 5746.271, 134, 4.644, 6836.645, 128, 2.693, 1349.867,
|
||||
123, 5.650, 5760.498, 118, 2.577, 13367.973, 113, 3.357, 17789.846, 110, 4.497, 4292.331, 108, 5.828, 12036.461,
|
||||
102, 5.621, 6256.778, 99, 1.14, 1059.38, 98, 0.66, 5856.48, 93, 2.32, 10213.29, 92, 0.77, 16730.46, 88, 1.50,
|
||||
11926.25, 86, 1.42, 5753.38, 85, 0.66, 155.42, 81, 1.64, 6681.22, 80, 4.11, 951.72, 66, 4.55, 5216.58, 65, 0.98,
|
||||
25132.30, 64, 4.19, 6040.35, 64, 0.52, 6290.19, 63, 1.51, 5643.18, 59, 6.18, 4164.31, 57, 2.30, 10973.56, 55,
|
||||
2.32, 11506.77, 55, 2.20, 1592.60, 55, 5.27, 3340.61, 54, 5.54, 553.57, 53, 5.04, 9917.70, 53, 0.92, 11371.70,
|
||||
52, 3.98, 17298.18, 52, 3.60, 10969.97, 49, 5.91, 3894.18, 49, 2.51, 6127.66, 48, 1.67, 12168.00, 46, 0.31,
|
||||
801.82, 42, 3.70, 10575.41, 42, 4.05, 10984.19, 40, 2.17, 7860.42, 40, 4.17, 26.30, 38, 5.82, 7058.60, 37, 3.39,
|
||||
6496.37, 36, 1.08, 6309.37, 36, 5.34, 7079.37, 34, 3.62, 11790.63, 32, 0.32, 16200.77, 31, 4.24, 3738.76, 29,
|
||||
4.55, 11856.22, 29, 1.26, 8635.94, 27, 3.45, 5884.93, 26, 5.08, 10177.26, 26, 5.38, 21228.39, 24, 2.26,
|
||||
11712.96, 24, 1.05, 242.73, 24, 5.59, 6069.78, 23, 3.63, 6284.06, 23, 1.64, 4732.03, 22, 3.46, 213.30, 21, 1.05,
|
||||
3496.03, 21, 3.92, 13916.02, 21, 4.01, 5230.81, 20, 5.16, 12352.85, 20, 0.69, 1990.75, 19, 2.73, 6062.66, 19,
|
||||
5.01, 11015.11, 18, 6.04, 6283.01, 18, 2.85, 7238.68, 18, 5.60, 6283.14, 18, 5.16, 17253.04, 18, 2.54, 14314.17,
|
||||
17, 1.58, 7.11, 17, 0.98, 3930.21, 17, 4.75, 17267.27, 16, 2.19, 6076.89, 16, 2.19, 18073.70, 16, 6.12, 3.52,
|
||||
16, 4.61, 9623.69, 16, 3.40, 16496.36, 15, 0.19, 9779.11, 15, 5.30, 13517.87, 15, 4.26, 3128.39, 15, 0.81,
|
||||
709.93, 14, 0.50, 25158.60, 14, 4.38, 4136.91, 13, 0.98, 65147.62, 13, 3.31, 154717.61, 13, 2.11, 1589.07, 13,
|
||||
1.92, 22483.85, 12, 6.03, 9225.54, 12, 1.53, 12559.04, 12, 5.82, 6282.10, 12, 5.61, 5642.20, 12, 2.38,
|
||||
167283.76, 12, 0.39, 12132.44, 12, 3.98, 4686.89, 12, 5.81, 12569.67, 12, 0.56, 5849.36, 11, 0.45, 6172.87, 11,
|
||||
5.80, 16858.48, 11, 6.22, 12146.67, 11, 2.27, 5429.88,
|
||||
435939, 5.784551, 6283.075850, 12363, 5.57935, 12566.15170, 1234, 3.1416, 0.0000, 879, 3.628, 77713.771, 569,
|
||||
1.870, 5573.143, 330, 5.470, 18849.228, 147, 4.480, 5507.553, 110, 2.842, 161000.686, 101, 2.815, 5223.694, 85,
|
||||
3.11, 1577.34, 65, 5.47, 775.52, 61, 1.38, 6438.50, 50, 4.42, 6286.60, 47, 3.66, 7084.90, 46, 5.39, 149854.40,
|
||||
42, 0.90, 10977.08, 40, 3.20, 5088.63, 35, 1.81, 5486.78, 32, 5.35, 3154.69, 30, 3.52, 796.30, 29, 4.62,
|
||||
4690.48, 28, 1.84, 4694.00, 27, 3.14, 71430.70, 27, 6.17, 6836.65, 26, 1.42, 2146.17, 25, 2.81, 1748.02, 24,
|
||||
2.18, 155.42, 23, 4.76, 7234.79, 21, 3.38, 7632.94, 21, 0.22, 4705.73, 20, 4.22, 1349.87, 20, 2.01, 1194.45, 20,
|
||||
4.58, 529.69, 19, 1.59, 6309.37, 18, 5.70, 6040.35, 18, 6.03, 4292.33, 17, 2.90, 9437.76, 17, 2.00, 8031.09, 17,
|
||||
5.78, 83996.85, 16, 0.05, 2544.31, 15, 0.95, 6127.66, 14, 0.36, 10447.39, 14, 1.48, 2352.87, 13, 0.77, 553.57,
|
||||
13, 5.48, 951.72, 13, 5.27, 6279.55, 13, 3.76, 6812.77, 11, 5.41, 6256.78, 10, 0.68, 1592.60, 10, 4.95, 398.15,
|
||||
10, 1.15, 3894.18, 10, 5.20, 244287.60, 10, 1.94, 11856.22, 9, 5.39, 25132.30, 8, 6.18, 1059.38, 8, 0.69,
|
||||
8429.24, 8, 5.85, 242.73, 7, 5.26, 14143.50, 7, 0.52, 801.82, 6, 2.24, 8635.94, 6, 4.00, 13367.97, 6, 2.77,
|
||||
90955.55, 6, 5.17, 7058.60, 5, 1.46, 233141.31, 5, 4.13, 7860.42, 5, 3.91, 26.30, 5, 3.89, 12036.46, 5, 5.58,
|
||||
6290.19, 5, 5.54, 1990.75, 5, 0.83, 11506.77, 5, 6.22, 6681.22, 4, 5.26, 10575.41, 4, 1.91, 7477.52, 4, 0.43,
|
||||
10213.29, 4, 1.09, 709.93, 4, 5.09, 11015.11, 4, 4.22, 88860.06, 4, 3.57, 7079.37, 4, 1.98, 6284.06, 4, 3.93,
|
||||
10973.56, 4, 6.18, 9917.70, 4, 0.36, 10177.26, 4, 2.75, 3738.76, 4, 3.33, 5643.18, 4, 5.36, 25158.60,
|
||||
14459, 4.27319, 6283.07585, 673, 3.917, 12566.152, 77, 0.00, 0.00, 25, 3.73, 18849.23, 4, 2.80, 6286.60,
|
||||
386, 2.564, 6283.076, 31, 2.27, 12566.15, 5, 3.44, 5573.14, 2, 2.05, 18849.23, 1, 2.06, 77713.77, 1, 4.41,
|
||||
161000.69, 1, 3.82, 149854.40, 1, 4.08, 6127.66, 1, 5.26, 6438.50,
|
||||
9, 1.22, 6283.08, 1, 0.66, 12566.15
|
||||
)
|
||||
__XL1 = (
|
||||
(22639.586, 0.78475822, 8328.691424623, 1.5229241, 25.0719, -0.123598, 4586.438, 0.1873974, 7214.06286536,
|
||||
-2.184756, -18.860, 0.08280, 2369.914, 2.5429520, 15542.75428998, -0.661832, 6.212, -0.04080, 769.026,
|
||||
3.140313, 16657.38284925, 3.04585, 50.144, -0.2472, 666.418, 1.527671, 628.30195521, -0.02664, 0.062, -0.0054,
|
||||
411.596, 4.826607, 16866.9323150, -1.28012, -1.07, -0.0059, 211.656, 4.115028, -1114.6285593, -3.70768, -43.93,
|
||||
0.2064, 205.436, 0.230523, 6585.7609101, -2.15812, -18.92, 0.0882, 191.956, 4.898507, 23871.4457146, 0.86109,
|
||||
31.28, -0.164, 164.729, 2.586078, 14914.4523348, -0.6352, 6.15, -0.035, 147.321, 5.45530, -7700.3894694,
|
||||
-1.5496, -25.01, 0.118, 124.988, 0.48608, 7771.3771450, -0.3309, 3.11, -0.020, 109.380, 3.88323, 8956.9933798,
|
||||
1.4963, 25.13, -0.129, 55.177, 5.57033, -1324.1780250, 0.6183, 7.3, -0.035, 45.100, 0.89898, 25195.623740,
|
||||
0.2428, 24.0, -0.129, 39.533, 3.81213, -8538.240890, 2.8030, 26.1, -0.118, 38.430, 4.30115, 22756.817155,
|
||||
-2.8466, -12.6, 0.042, 36.124, 5.49587, 24986.074274, 4.5688, 75.2, -0.371, 30.773, 1.94559, 14428.125731,
|
||||
-4.3695, -37.7, 0.166, 28.397, 3.28586, 7842.364821, -2.2114, -18.8, 0.077, 24.358, 5.64142, 16171.056245,
|
||||
-0.6885, 6.3, -0.046, 18.585, 4.41371, -557.314280, -1.8538, -22.0, 0.10, 17.954, 3.58454, 8399.679100,
|
||||
-0.3576, 3.2, -0.03, 14.530, 4.9416, 23243.143759, 0.888, 31.2, -0.16, 14.380, 0.9709, 32200.137139, 2.384,
|
||||
56.4, -0.29, 14.251, 5.7641, -2.301200, 1.523, 25.1, -0.12, 13.899, 0.3735, 31085.508580, -1.324, 12.4, -0.08,
|
||||
13.194, 1.7595, -9443.319984, -5.231, -69.0, 0.33, 9.679, 3.0997, -16029.080894, -3.072, -50.1, 0.24, 9.366,
|
||||
0.3016, 24080.995180, -3.465, -19.9, 0.08, 8.606, 4.1582, -1742.930514, -3.681, -44.0, 0.21, 8.453, 2.8416,
|
||||
16100.068570, 1.192, 28.2, -0.14, 8.050, 2.6292, 14286.150380, -0.609, 6.1, -0.03, 7.630, 6.2388, 17285.684804,
|
||||
3.019, 50.2, -0.25, 7.447, 1.4845, 1256.603910, -0.053, 0.1, -0.01, 7.371, 0.2736, 5957.458955, -2.131, -19.0,
|
||||
0.09, 7.063, 5.6715, 33.757047, -0.308, -3.6, 0.02, 6.383, 4.7843, 7004.513400, 2.141, 32.4, -0.16, 5.742,
|
||||
2.6572, 32409.686605, -1.942, 5, -0.05, 4.374, 4.3443, 22128.51520, -2.820, -13, 0.05, 3.998, 3.2545,
|
||||
33524.31516, 1.766, 49, -0.25, 3.210, 2.2443, 14985.44001, -2.516, -16, 0.06, 2.915, 1.7138, 24499.74767,
|
||||
0.834, 31, -0.17, 2.732, 1.9887, 13799.82378, -4.343, -38, 0.17, 2.568, 5.4122, -7072.08751, -1.576, -25, 0.11,
|
||||
2.521, 3.2427, 8470.66678, -2.238, -19, 0.07, 2.489, 4.0719, -486.32660, -3.734, -44, 0.20, 2.146, 5.6135,
|
||||
-1952.47998, 0.645, 7, -0.03, 1.978, 2.7291, 39414.20000, 0.199, 37, -0.21, 1.934, 1.5682, 33314.76570, 6.092,
|
||||
100, -0.5, 1.871, 0.4166, 30457.20662, -1.297, 12, -0.1, 1.753, 2.0582, -8886.00570, -3.38, -47, 0.2, 1.437,
|
||||
2.386, -695.87607, 0.59, 7, 0, 1.373, 3.026, -209.54947, 4.33, 51, -0.2, 1.262, 5.940, 16728.37052, 1.17, 28,
|
||||
-0.1, 1.224, 6.172, 6656.74859, -4.04, -41, 0.2, 1.187, 5.873, 6099.43431, -5.89, -63, 0.3, 1.177, 1.014,
|
||||
31571.83518, 2.41, 56, -0.3, 1.162, 3.840, 9585.29534, 1.47, 25, -0.1, 1.143, 5.639, 8364.73984, -2.18, -19,
|
||||
0.1, 1.078, 1.229, 70.98768, -1.88, -22, 0.1, 1.059, 3.326, 40528.82856, 3.91, 81, -0.4, 0.990, 5.013,
|
||||
40738.37803, -0.42, 30, -0.2, 0.948, 5.687, -17772.01141, -6.75, -94, 0.5, 0.876, 0.298, -0.35232, 0, 0, 0,
|
||||
0.822, 2.994, 393.02097, 0, 0, 0, 0.788, 1.836, 8326.39022, 3.05, 50, -0.2, 0.752, 4.985, 22614.84180, 0.91,
|
||||
31, -0.2, 0.740, 2.875, 8330.99262, 0, 0, 0, 0.669, 0.744, -24357.77232, -4.60, -75, 0.4, 0.644, 1.314,
|
||||
8393.12577, -2.18, -19, 0.1, 0.639, 5.888, 575.33849, 0, 0, 0, 0.635, 1.116, 23385.11911, -2.87, -13, 0, 0.584,
|
||||
5.197, 24428.75999, 2.71, 53, -0.3, 0.583, 3.513, -9095.55517, 0.95, 4, 0, 0.572, 6.059, 29970.88002, -5.03,
|
||||
-32, 0.1, 0.565, 2.960, 0.32863, 1.52, 25, -0.1, 0.561, 4.001, -17981.56087, -2.43, -43, 0.2, 0.557, 0.529,
|
||||
7143.07519, -0.30, 3, 0, 0.546, 2.311, 25614.37623, 4.54, 75, -0.4, 0.536, 4.229, 15752.30376, -4.99, -45, 0.2,
|
||||
0.493, 3.316, -8294.9344, -1.83, -29, 0.1, 0.491, 1.744, 8362.4485, 1.21, 21, -0.1, 0.478, 1.803, -10071.6219,
|
||||
-5.20, -69, 0.3, 0.454, 0.857, 15333.2048, 3.66, 57, -0.3, 0.445, 2.071, 8311.7707, -2.18, -19, 0.1, 0.426,
|
||||
0.345, 23452.6932, -3.44, -20, 0.1, 0.420, 4.941, 33733.8646, -2.56, -2, 0, 0.413, 1.642, 17495.2343, -1.31,
|
||||
-1, 0, 0.404, 1.458, 23314.1314, -0.99, 9, -0.1, 0.395, 2.132, 38299.5714, -3.51, -6, 0, 0.382, 2.700,
|
||||
31781.3846, -1.92, 5, 0, 0.375, 4.827, 6376.2114, 2.17, 32, -0.2, 0.361, 3.867, 16833.1753, -0.97, 3, 0, 0.358,
|
||||
5.044, 15056.4277, -4.40, -38, 0.2, 0.350, 5.157, -8257.7037, -3.40, -47, 0.2, 0.344, 4.233, 157.7344, 0, 0, 0,
|
||||
0.340, 2.672, 13657.8484, -0.58, 6, 0, 0.329, 5.610, 41853.0066, 3.29, 74, -0.4, 0.325, 5.895, -39.8149, 0, 0,
|
||||
0, 0.309, 4.387, 21500.2132, -2.79, -13, 0.1, 0.302, 1.278, 786.0419, 0, 0, 0, 0.302, 5.341, -24567.3218,
|
||||
-0.27, -24, 0.1, 0.301, 1.045, 5889.8848, -1.57, -12, 0, 0.294, 4.201, -2371.2325, -3.65, -44, 0.2, 0.293,
|
||||
3.704, 21642.1886, -6.55, -57, 0.2, 0.290, 4.069, 32828.4391, 2.36, 56, -0.3, 0.289, 3.472, 31713.8105, -1.35,
|
||||
12, -0.1, 0.285, 5.407, -33.7814, 0.31, 4, 0, 0.283, 5.998, -16.9207, -3.71, -44, 0.2, 0.283, 2.772,
|
||||
38785.8980, 0.23, 37, -0.2, 0.274, 5.343, 15613.7420, -2.54, -16, 0.1, 0.263, 3.997, 25823.9257, 0.22, 24,
|
||||
-0.1, 0.254, 0.600, 24638.3095, -1.61, 2, 0, 0.253, 1.344, 6447.1991, 0.29, 10, -0.1, 0.250, 0.887, 141.9754,
|
||||
-3.76, -44, 0.2, 0.247, 0.317, 5329.1570, -2.10, -19, 0.1, 0.245, 0.141, 36.0484, -3.71, -44, 0.2, 0.231,
|
||||
2.287, 14357.1381, -2.49, -16, 0.1, 0.227, 5.158, 2.6298, 0, 0, 0, 0.219, 5.085, 47742.8914, 1.72, 63, -0.3,
|
||||
0.211, 2.145, 6638.7244, -2.18, -19, 0.1, 0.201, 4.415, 39623.7495, -4.13, -14, 0, 0.194, 2.091, 588.4927, 0,
|
||||
0, 0, 0.193, 3.057, -15400.7789, -3.10, -50, 0, 0.186, 5.598, 16799.3582, -0.72, 6, 0, 0.185, 3.886, 1150.6770,
|
||||
0, 0, 0, 0.183, 1.619, 7178.0144, 1.52, 25, 0, 0.181, 2.635, 8328.3391, 1.52, 25, 0, 0.181, 2.077, 8329.0437,
|
||||
1.52, 25, 0, 0.179, 3.215, -9652.8694, -0.90, -18, 0, 0.176, 1.716, -8815.0180, -5.26, -69, 0, 0.175, 5.673,
|
||||
550.7553, 0, 0, 0, 0.170, 2.060, 31295.0580, -5.6, -39, 0, 0.167, 1.239, 7211.7617, -0.7, 6, 0, 0.165, 4.499,
|
||||
14967.4158, -0.7, 6, 0, 0.164, 3.595, 15540.4531, 0.9, 31, 0, 0.164, 4.237, 522.3694, 0, 0, 0, 0.163, 4.633,
|
||||
15545.0555, -2.2, -19, 0, 0.161, 0.478, 6428.0209, -2.2, -19, 0, 0.158, 2.03, 13171.5218, -4.3, -38, 0, 0.157,
|
||||
2.28, 7216.3641, -3.7, -44, 0, 0.154, 5.65, 7935.6705, 1.5, 25, 0, 0.152, 0.46, 29828.9047, -1.3, 12, 0, 0.151,
|
||||
1.19, -0.7113, 0, 0, 0, 0.150, 1.42, 23942.4334, -1.0, 9, 0, 0.144, 2.75, 7753.3529, 1.5, 25, 0, 0.137, 2.08,
|
||||
7213.7105, -2.2, -19, 0, 0.137, 1.44, 7214.4152, -2.2, -19, 0, 0.136, 4.46, -1185.6162, -1.8, -22, 0, 0.136,
|
||||
3.03, 8000.1048, -2.2, -19, 0, 0.134, 2.83, 14756.7124, -0.7, 6, 0, 0.131, 5.05, 6821.0419, -2.2, -19, 0,
|
||||
0.128, 5.99, -17214.6971, -4.9, -72, 0, 0.127, 5.35, 8721.7124, 1.5, 25, 0, 0.126, 4.49, 46628.2629, -2.0, 19,
|
||||
0, 0.125, 5.94, 7149.6285, 1.5, 25, 0, 0.124, 1.09, 49067.0695, 1.1, 55, 0, 0.121, 2.88, 15471.7666, 1.2, 28,
|
||||
0, 0.111, 3.92, 41643.4571, 7.6, 125, -1, 0.110, 1.96, 8904.0299, 1.5, 25, 0, 0.106, 3.30, -18.0489, -2.2, -19,
|
||||
0, 0.105, 2.30, -4.9310, 1.5, 25, 0, 0.104, 2.22, -6.5590, -1.9, -22, 0, 0.101, 1.44, 1884.9059, -0.1, 0, 0,
|
||||
0.100, 5.92, 5471.1324, -5.9, -63, 0, 0.099, 1.12, 15149.7333, -0.7, 6, 0, 0.096, 4.73, 15508.9972, -0.4, 10,
|
||||
0, 0.095, 5.18, 7230.9835, 1.5, 25, 0, 0.093, 3.37, 39900.5266, 3.9, 81, 0, 0.092, 2.01, 25057.0619, 2.7, 53,
|
||||
0, 0.092, 1.21, -79.6298, 0, 0, 0, 0.092, 1.65, -26310.2523, -4.0, -68, 0, 0.091, 1.01, 42062.5561, -1.0, 23,
|
||||
0, 0.090, 6.10, 29342.5781, -5.0, -32, 0, 0.090, 4.43, 15542.4020, -0.7, 6, 0, 0.090, 3.80, 15543.1066, -0.7,
|
||||
6, 0, 0.089, 4.15, 6063.3859, -2.2, -19, 0, 0.086, 4.03, 52.9691, 0, 0, 0, 0.085, 0.49, 47952.4409, -2.6, 11,
|
||||
0, 0.085, 1.60, 7632.8154, 2.1, 32, 0, 0.084, 0.22, 14392.0773, -0.7, 6, 0, 0.083, 6.22, 6028.4466, -4.0, -41,
|
||||
0, 0.083, 0.63, -7909.9389, 2.8, 26, 0, 0.083, 5.20, -77.5523, 0, 0, 0, 0.082, 2.74, 8786.1467, -2.2, -19, 0,
|
||||
0.080, 2.43, 9166.5428, -2.8, -26, 0, 0.080, 3.70, -25405.1732, 4.1, 27, 0, 0.078, 5.68, 48857.5200, 5.4, 106,
|
||||
-1, 0.077, 1.85, 8315.5735, -2.2, -19, 0, 0.075, 5.46, -18191.1103, 1.9, 8, 0, 0.075, 1.41, -16238.6304, 1.3,
|
||||
1, 0, 0.074, 5.06, 40110.0761, -0.4, 30, 0, 0.072, 2.10, 64.4343, -3.7, -44, 0, 0.071, 2.17, 37671.2695, -3.5,
|
||||
-6, 0, 0.069, 1.71, 16693.4313, -0.7, 6, 0, 0.069, 3.33, -26100.7028, -8.3, -119, 1, 0.068, 1.09, 8329.4028,
|
||||
1.5, 25, 0, 0.068, 3.62, 8327.9801, 1.5, 25, 0, 0.068, 2.41, 16833.1509, -1.0, 3, 0, 0.067, 3.40, 24709.2971,
|
||||
-3.5, -20, 0, 0.067, 1.65, 8346.7156, -0.3, 3, 0, 0.066, 2.61, 22547.2677, 1.5, 39, 0, 0.066, 3.50, 15576.5113,
|
||||
-1.0, 3, 0, 0.065, 5.76, 33037.9886, -2.0, 5, 0, 0.065, 4.58, 8322.1325, -0.3, 3, 0, 0.065, 6.20, 17913.9868,
|
||||
3.0, 50, 0, 0.065, 1.50, 22685.8295, -1.0, 9, 0, 0.065, 2.37, 7180.3058, -1.9, -15, 0, 0.064, 1.06, 30943.5332,
|
||||
2.4, 56, 0, 0.064, 1.89, 8288.8765, 1.5, 25, 0, 0.064, 4.70, 6.0335, 0.3, 4, 0, 0.063, 2.83, 8368.5063, 1.5,
|
||||
25, 0, 0.063, 5.66, -2580.7819, 0.7, 7, 0, 0.062, 3.78, 7056.3285, -2.2, -19, 0, 0.061, 1.49, 8294.9100, 1.8,
|
||||
29, 0, 0.061, 0.12, -10281.1714, -0.9, -18, 0, 0.061, 3.06, -8362.4729, -1.2, -21, 0, 0.061, 4.43, 8170.9571,
|
||||
1.5, 25, 0, 0.059, 5.78, -13.1179, -3.7, -44, 0, 0.059, 5.97, 6625.5702, -2.2, -19, 0, 0.058, 5.01, -0.5080,
|
||||
-0.3, 0, 0, 0.058, 2.73, 7161.0938, -2.2, -19, 0, 0.057, 0.19, 7214.0629, -2.2, -19, 0, 0.057, 4.00,
|
||||
22199.5029, -4.7, -35, 0, 0.057, 5.38, 8119.1420, 5.8, 76, 0, 0.056, 1.07, 7542.6495, 1.5, 25, 0, 0.056, 0.28,
|
||||
8486.4258, 1.5, 25, 0, 0.054, 4.19, 16655.0816, 4.6, 75, 0, 0.053, 0.72, 7267.0320, -2.2, -19, 0, 0.053, 3.12,
|
||||
12.6192, 0.6, 7, 0, 0.052, 2.99, -32896.013, -1.8, -49, 0, 0.052, 3.46, 1097.708, 0, 0, 0, 0.051, 5.37,
|
||||
-6443.786, -1.6, -25, 0, 0.051, 1.35, 7789.401, -2.2, -19, 0, 0.051, 5.83, 40042.502, 0.2, 38, 0, 0.051, 3.63,
|
||||
9114.733, 1.5, 25, 0, 0.050, 1.51, 8504.484, -2.5, -22, 0, 0.050, 5.23, 16659.684, 1.5, 25, 0, 0.050, 1.15,
|
||||
7247.820, -2.5, -23, 0, 0.047, 0.25, -1290.421, 0.3, 0, 0, 0.047, 4.67, -32686.464, -6.1, -100, 0, 0.047, 3.49,
|
||||
548.678, 0, 0, 0, 0.047, 2.37, 6663.308, -2.2, -19, 0, 0.046, 0.98, 1572.084, 0, 0, 0, 0.046, 2.04, 14954.262,
|
||||
-0.7, 6, 0, 0.046, 3.72, 6691.693, -2.2, -19, 0, 0.045, 6.19, -235.287, 0, 0, 0, 0.044, 2.96, 32967.001, -0.1,
|
||||
27, 0, 0.044, 3.82, -1671.943, -5.6, -66, 0, 0.043, 5.82, 1179.063, 0, 0, 0, 0.043, 0.07, 34152.617, 1.7, 49,
|
||||
0, 0.043, 3.71, 6514.773, -0.3, 0, 0, 0.043, 5.62, 15.732, -2.5, -23, 0, 0.043, 5.80, 8351.233, -2.2, -19, 0,
|
||||
0.042, 0.27, 7740.199, 1.5, 25, 0, 0.042, 6.14, 15385.020, -0.7, 6, 0, 0.042, 6.13, 7285.051, -4.1, -41, 0,
|
||||
0.041, 1.27, 32757.451, 4.2, 78, 0, 0.041, 4.46, 8275.722, 1.5, 25, 0, 0.040, 0.23, 8381.661, 1.5, 25, 0,
|
||||
0.040, 5.87, -766.864, 2.5, 29, 0, 0.040, 1.66, 254.431, 0, 0, 0, 0.040, 0.40, 9027.981, -0.4, 0, 0, 0.040,
|
||||
2.96, 7777.936, 1.5, 25, 0, 0.039, 4.67, 33943.068, 6.1, 100, 0, 0.039, 3.52, 8326.062, 1.5, 25, 0, 0.039,
|
||||
3.75, 21013.887, -6.5, -57, 0, 0.039, 5.60, 606.978, 0, 0, 0, 0.039, 1.19, 8331.321, 1.5, 25, 0, 0.039, 2.84,
|
||||
7211.433, -2.2, -19, 0, 0.038, 0.67, 7216.693, -2.2, -19, 0, 0.038, 6.22, 25161.867, 0.6, 28, 0, 0.038, 4.40,
|
||||
7806.322, 1.5, 25, 0, 0.038, 4.16, 9179.168, -2.2, -19, 0, 0.037, 4.73, 14991.999, -0.7, 6, 0, 0.036, 0.35,
|
||||
67.514, -0.6, -7, 0, 0.036, 3.70, 25266.611, -1.6, 0, 0, 0.036, 5.39, 16328.796, -0.7, 6, 0, 0.035, 1.44,
|
||||
7174.248, -2.2, -19, 0, 0.035, 5.00, 15684.730, -4.4, -38, 0, 0.035, 0.39, -15.419, -2.2, -19, 0, 0.035, 6.07,
|
||||
15020.385, -0.7, 6, 0, 0.034, 6.01, 7371.797, -2.2, -19, 0, 0.034, 0.96, -16623.626, -3.4, -54, 0, 0.033, 6.24,
|
||||
9479.368, 1.5, 25, 0, 0.033, 3.21, 23661.896, 5.2, 82, 0, 0.033, 4.06, 8311.418, -2.2, -19, 0, 0.033, 2.40,
|
||||
1965.105, 0, 0, 0, 0.033, 5.17, 15489.785, -0.7, 6, 0, 0.033, 5.03, 21986.540, 0.9, 31, 0, 0.033, 4.10,
|
||||
16691.140, 2.7, 46, 0, 0.033, 5.13, 47114.589, 1.7, 63, 0, 0.033, 4.45, 8917.184, 1.5, 25, 0, 0.033, 4.23,
|
||||
2.078, 0, 0, 0, 0.032, 2.33, 75.251, 1.5, 25, 0, 0.032, 2.10, 7253.878, -2.2, -19, 0, 0.032, 3.11, -0.224, 1.5,
|
||||
25, 0, 0.032, 4.43, 16640.462, -0.7, 6, 0, 0.032, 5.68, 8328.363, 0, 0, 0, 0.031, 5.32, 8329.020, 3.0, 50, 0,
|
||||
0.031, 3.70, 16118.093, -0.7, 6, 0, 0.030, 3.67, 16721.817, -0.7, 6, 0, 0.030, 5.27, -1881.492, -1.2, -15, 0,
|
||||
0.030, 5.72, 8157.839, -2.2, -19, 0, 0.029, 5.73, -18400.313, -6.7, -94, 0, 0.029, 2.76, 16.000, -2.2, -19, 0,
|
||||
0.029, 1.75, 8879.447, 1.5, 25, 0, 0.029, 0.32, 8851.061, 1.5, 25, 0, 0.029, 0.90, 14704.903, 3.7, 57, 0,
|
||||
0.028, 2.90, 15595.723, -0.7, 6, 0, 0.028, 5.88, 16864.631, 0.2, 24, 0, 0.028, 0.63, 16869.234, -2.8, -26, 0,
|
||||
0.028, 4.04, -18609.863, -2.4, -43, 0, 0.027, 5.83, 6727.736, -5.9, -63, 0, 0.027, 6.12, 418.752, 4.3, 51, 0,
|
||||
0.027, 0.14, 41157.131, 3.9, 81, 0, 0.026, 3.80, 15.542, 0, 0, 0, 0.026, 1.68, 50181.698, 4.8, 99, -1, 0.026,
|
||||
0.32, 315.469, 0, 0, 0, 0.025, 5.67, 19.188, 0.3, 0, 0, 0.025, 3.16, 62.133, -2.2, -19, 0, 0.025, 3.76,
|
||||
15502.939, -0.7, 6, 0, 0.025, 4.53, 45999.961, -2.0, 19, 0, 0.024, 3.21, 837.851, -4.4, -51, 0, 0.024, 2.82,
|
||||
38157.596, 0.3, 37, 0, 0.024, 5.21, 15540.124, -0.7, 6, 0, 0.024, 0.26, 14218.576, 0, 13, 0, 0.024, 3.01,
|
||||
15545.384, -0.7, 6, 0, 0.024, 1.16, -17424.247, -0.6, -21, 0, 0.023, 2.34, -67.574, 0.6, 7, 0, 0.023, 2.44,
|
||||
18.024, -1.9, -22, 0, 0.023, 3.70, 469.400, 0, 0, 0, 0.023, 0.72, 7136.511, -2.2, -19, 0, 0.023, 4.50,
|
||||
15582.569, -0.7, 6, 0, 0.023, 2.80, -16586.395, -4.9, -72, 0, 0.023, 1.51, 80.182, 0, 0, 0, 0.023, 1.09,
|
||||
5261.583, -1.5, -12, 0, 0.023, 0.56, 54956.954, -0.5, 44, 0, 0.023, 4.01, 8550.860, -2.2, -19, 0, 0.023, 4.46,
|
||||
38995.448, -4.1, -14, 0, 0.023, 3.82, 2358.126, 0, 0, 0, 0.022, 3.77, 32271.125, 0.5, 34, 0, 0.022, 0.82,
|
||||
15935.775, -0.7, 6, 0, 0.022, 1.07, 24013.421, -2.9, -13, 0, 0.022, 0.40, 8940.078, -2.2, -19, 0, 0.022, 2.06,
|
||||
15700.489, -0.7, 6, 0, 0.022, 4.27, 15124.002, -5.0, -45, 0, 0.021, 1.16, 56071.583, 3.2, 88, 0, 0.021, 5.58,
|
||||
9572.189, -2.2, -19, 0, 0.020, 1.70, -17.273, -3.7, -44, 0, 0.020, 3.05, 214.617, 0, 0, 0, 0.020, 4.41,
|
||||
8391.048, -2.2, -19, 0, 0.020, 5.95, 23869.145, 2.4, 56, 0, 0.020, 0.42, 40947.927, -4.7, -21, 0, 0.019, 1.39,
|
||||
5818.897, 0.3, 10, 0, 0.019, 0.71, 23873.747, -0.7, 6, 0, 0.019, 2.81, 7291.615, -2.2, -19, 0, 0.019, 5.09,
|
||||
8428.018, -2.2, -19, 0, 0.019, 4.14, 6518.187, -1.6, -12, 0, 0.019, 3.85, 21.330, 0, 0, 0, 0.018, 0.66,
|
||||
14445.046, -0.7, 6, 0, 0.018, 1.65, 0.966, -4.0, -48, 0, 0.018, 5.64, -17143.709, -6.8, -94, 0, 0.018, 6.01,
|
||||
7736.432, -2.2, -19, 0, 0.018, 2.74, 31153.083, -1.9, 5, 0, 0.018, 4.58, 6116.355, -2.2, -19, 0, 0.018, 2.28,
|
||||
46.401, 0.3, 0, 0, 0.018, 3.80, 10213.597, 1.4, 25, 0, 0.018, 2.84, 56281.132, -1.1, 36, 0, 0.018, 3.53,
|
||||
8249.062, 1.5, 25, 0, 0.017, 4.43, 20871.911, -3, -13, 0, 0.017, 4.44, 627.596, 0, 0, 0, 0.017, 1.85, 628.308,
|
||||
0, 0, 0, 0.017, 1.19, 8408.321, 2, 25, 0, 0.017, 1.95, 7214.056, -2, -19, 0, 0.017, 1.57, 7214.070, -2, -19, 0,
|
||||
0.017, 1.65, 13870.811, -6, -60, 0, 0.017, 0.30, 22.542, -4, -44, 0, 0.017, 2.62, -119.445, 0, 0, 0, 0.016,
|
||||
4.87, 5747.909, 2, 32, 0, 0.016, 4.45, 14339.108, -1, 6, 0, 0.016, 1.83, 41366.680, 0, 30, 0, 0.016, 4.53,
|
||||
16309.618, -3, -23, 0, 0.016, 2.54, 15542.754, -1, 6, 0, 0.016, 6.05, 1203.646, 0, 0, 0, 0.015, 5.2, 2751.147,
|
||||
0, 0, 0, 0.015, 1.8, -10699.924, -5, -69, 0, 0.015, 0.4, 22824.391, -3, -20, 0, 0.015, 2.1, 30666.756, -6, -39,
|
||||
0, 0.015, 2.1, 6010.417, -2, -19, 0, 0.015, 0.7, -23729.470, -5, -75, 0, 0.015, 1.4, 14363.691, -1, 6, 0,
|
||||
0.015, 5.8, 16900.689, -2, 0, 0, 0.015, 5.2, 23800.458, 3, 53, 0, 0.015, 5.3, 6035.000, -2, -19, 0, 0.015, 1.2,
|
||||
8251.139, 2, 25, 0, 0.015, 3.6, -8.860, 0, 0, 0, 0.015, 0.8, 882.739, 0, 0, 0, 0.015, 3.0, 1021.329, 0, 0, 0,
|
||||
0.015, 0.6, 23296.107, 1, 31, 0, 0.014, 5.4, 7227.181, 2, 25, 0, 0.014, 0.1, 7213.352, -2, -19, 0, 0.014, 4.0,
|
||||
15506.706, 3, 50, 0, 0.014, 3.4, 7214.774, -2, -19, 0, 0.014, 4.6, 6665.385, -2, -19, 0, 0.014, 0.1, -8.636,
|
||||
-2, -22, 0, 0.014, 3.1, 15465.202, -1, 6, 0, 0.014, 4.9, 508.863, 0, 0, 0, 0.014, 3.5, 8406.244, 2, 25, 0,
|
||||
0.014, 1.3, 13313.497, -8, -82, 0, 0.014, 2.8, 49276.619, -3, 0, 0, 0.014, 0.1, 30528.194, -3, -10, 0, 0.013,
|
||||
1.7, 25128.050, 1, 31, 0, 0.013, 2.9, 14128.405, -1, 6, 0, 0.013, 3.4, 57395.761, 3, 80, 0, 0.013, 2.7,
|
||||
13029.546, -1, 6, 0, 0.013, 3.9, 7802.556, -2, -19, 0, 0.013, 1.6, 8258.802, -2, -19, 0, 0.013, 2.2, 8417.709,
|
||||
-2, -19, 0, 0.013, 0.7, 9965.210, -2, -19, 0, 0.013, 3.4, 50391.247, 0, 48, 0, 0.013, 3.0, 7134.433, -2, -19,
|
||||
0, 0.013, 2.9, 30599.182, -5, -31, 0, 0.013, 3.6, -9723.857, 1, 0, 0, 0.013, 4.8, 7607.084, -2, -19, 0, 0.012,
|
||||
0.8, 23837.689, 1, 35, 0, 0.012, 3.6, 4.409, -4, -44, 0, 0.012, 5.0, 16657.031, 3, 50, 0, 0.012, 4.4,
|
||||
16657.735, 3, 50, 0, 0.012, 1.1, 15578.803, -4, -38, 0, 0.012, 6.0, -11.490, 0, 0, 0, 0.012, 1.9, 8164.398, 0,
|
||||
0, 0, 0.012, 2.4, 31852.372, -4, -17, 0, 0.012, 2.4, 6607.085, -2, -19, 0, 0.012, 4.2, 8359.870, 0, 0, 0,
|
||||
0.012, 0.5, 5799.713, -2, -19, 0, 0.012, 2.7, 7220.622, 0, 0, 0, 0.012, 4.3, -139.720, 0, 0, 0, 0.012, 2.3,
|
||||
13728.836, -2, -16, 0, 0.011, 3.6, 14912.146, 1, 31, 0, 0.011, 4.7, 14916.748, -2, -19, 0),
|
||||
(1.67680, 4.66926, 628.301955, -0.0266, 0.1, -0.005, 0.51642, 3.3721, 6585.760910, -2.158, -18.9, 0.09, 0.41383,
|
||||
5.7277, 14914.452335, -0.635, 6.2, -0.04, 0.37115, 3.9695, 7700.389469, 1.550, 25.0, -0.12, 0.27560, 0.7416,
|
||||
8956.993380, 1.496, 25.1, -0.13, 0.24599, 4.2253, -2.301200, 1.523, 25.1, -0.12, 0.07118, 0.1443, 7842.36482,
|
||||
-2.211, -19, 0.08, 0.06128, 2.4998, 16171.05625, -0.688, 6, 0, 0.04516, 0.443, 8399.67910, -0.36, 3, 0,
|
||||
0.04048, 5.771, 14286.15038, -0.61, 6, 0, 0.03747, 4.626, 1256.60391, -0.05, 0, 0, 0.03707, 3.415, 5957.45895,
|
||||
-2.13, -19, 0.1, 0.03649, 1.800, 23243.14376, 0.89, 31, -0.2, 0.02438, 0.042, 16029.08089, 3.07, 50, -0.2,
|
||||
0.02165, 1.017, -1742.93051, -3.68, -44, 0.2, 0.01923, 3.097, 17285.68480, 3.02, 50, -0.3, 0.01692, 1.280,
|
||||
0.3286, 1.52, 25, -0.1, 0.01361, 0.298, 8326.3902, 3.05, 50, -0.2, 0.01293, 4.013, 7072.0875, 1.58, 25, -0.1,
|
||||
0.01276, 4.413, 8330.9926, 0, 0, 0, 0.01270, 0.101, 8470.6668, -2.24, -19, 0.1, 0.01097, 1.203, 22128.5152,
|
||||
-2.82, -13, 0, 0.01088, 2.545, 15542.7543, -0.66, 6, 0, 0.00835, 0.190, 7214.0629, -2.18, -19, 0.1, 0.00734,
|
||||
4.855, 24499.7477, 0.83, 31, -0.2, 0.00686, 5.130, 13799.8238, -4.34, -38, 0.2, 0.00631, 0.930, -486.3266,
|
||||
-3.73, -44, 0, 0.00585, 0.699, 9585.2953, 1.5, 25, 0, 0.00566, 4.073, 8328.3391, 1.5, 25, 0, 0.00566, 0.638,
|
||||
8329.0437, 1.5, 25, 0, 0.00539, 2.472, -1952.4800, 0.6, 7, 0, 0.00509, 2.88, -0.7113, 0, 0, 0, 0.00469, 3.56,
|
||||
30457.2066, -1.3, 12, 0, 0.00387, 0.78, -0.3523, 0, 0, 0, 0.00378, 1.84, 22614.8418, 0.9, 31, 0, 0.00362, 5.53,
|
||||
-695.8761, 0.6, 7, 0, 0.00317, 2.80, 16728.3705, 1.2, 28, 0, 0.00303, 6.07, 157.7344, 0, 0, 0, 0.00300, 2.53,
|
||||
33.7570, -0.3, -4, 0, 0.00295, 4.16, 31571.8352, 2.4, 56, 0, 0.00289, 5.98, 7211.7617, -0.7, 6, 0, 0.00285,
|
||||
2.06, 15540.4531, 0.9, 31, 0, 0.00283, 2.65, 2.6298, 0, 0, 0, 0.00282, 6.17, 15545.0555, -2.2, -19, 0, 0.00278,
|
||||
1.23, -39.8149, 0, 0, 0, 0.00272, 3.82, 7216.3641, -3.7, -44, 0, 0.00270, 4.37, 70.9877, -1.9, -22, 0, 0.00256,
|
||||
5.81, 13657.8484, -0.6, 6, 0, 0.00244, 5.64, -0.2237, 1.5, 25, 0, 0.00240, 2.96, 8311.7707, -2.2, -19, 0,
|
||||
0.00239, 0.87, -33.7814, 0.3, 4, 0, 0.00216, 2.31, 15.9995, -2.2, -19, 0, 0.00186, 3.46, 5329.1570, -2.1, -19,
|
||||
0, 0.00169, 2.40, 24357.772, 4.6, 75, 0, 0.00161, 5.80, 8329.403, 1.5, 25, 0, 0.00161, 5.20, 8327.980, 1.5, 25,
|
||||
0, 0.00160, 4.26, 23385.119, -2.9, -13, 0, 0.00156, 1.26, 550.755, 0, 0, 0, 0.00155, 1.25, 21500.213, -2.8,
|
||||
-13, 0, 0.00152, 0.60, -16.921, -3.7, -44, 0, 0.00150, 2.71, -79.630, 0, 0, 0, 0.00150, 5.29, 15.542, 0, 0, 0,
|
||||
0.00148, 1.06, -2371.232, -3.7, -44, 0, 0.00141, 0.77, 8328.691, 1.5, 25, 0, 0.00141, 3.67, 7143.075, -0.3, 0,
|
||||
0, 0.00138, 5.45, 25614.376, 4.5, 75, 0, 0.00129, 4.90, 23871.446, 0.9, 31, 0, 0.00126, 4.03, 141.975, -3.8,
|
||||
-44, 0, 0.00124, 6.01, 522.369, 0, 0, 0, 0.00120, 4.94, -10071.622, -5.2, -69, 0, 0.00118, 5.07, -15.419, -2.2,
|
||||
-19, 0, 0.00107, 3.49, 23452.693, -3.4, -20, 0, 0.00104, 4.78, 17495.234, -1.3, 0, 0, 0.00103, 1.44, -18.049,
|
||||
-2.2, -19, 0, 0.00102, 5.63, 15542.402, -0.7, 6, 0, 0.00102, 2.59, 15543.107, -0.7, 6, 0, 0.00100, 4.11,
|
||||
-6.559, -1.9, -22, 0, 0.00097, 0.08, 15400.779, 3.1, 50, 0, 0.00096, 5.84, 31781.385, -1.9, 5, 0, 0.00094,
|
||||
1.08, 8328.363, 0, 0, 0, 0.00094, 2.46, 16799.358, -0.7, 6, 0, 0.00094, 1.69, 6376.211, 2.2, 32, 0, 0.00093,
|
||||
3.64, 8329.020, 3.0, 50, 0, 0.00093, 2.65, 16655.082, 4.6, 75, 0, 0.00090, 1.90, 15056.428, -4.4, -38, 0,
|
||||
0.00089, 1.59, 52.969, 0, 0, 0, 0.00088, 2.02, -8257.704, -3.4, -47, 0, 0.00088, 3.02, 7213.711, -2.2, -19, 0,
|
||||
0.00087, 0.50, 7214.415, -2.2, -19, 0, 0.00087, 0.49, 16659.684, 1.5, 25, 0, 0.00082, 5.64, -4.931, 1.5, 25, 0,
|
||||
0.00079, 5.17, 13171.522, -4.3, -38, 0, 0.00076, 3.60, 29828.905, -1.3, 12, 0, 0.00076, 4.08, 24567.322, 0.3,
|
||||
24, 0, 0.00076, 4.58, 1884.906, -0.1, 0, 0, 0.00073, 0.33, 31713.811, -1.4, 12, 0, 0.00073, 0.93, 32828.439,
|
||||
2.4, 56, 0, 0.00071, 5.91, 38785.898, 0.2, 37, 0, 0.00069, 2.20, 15613.742, -2.5, -16, 0, 0.00066, 3.87,
|
||||
15.732, -2.5, -23, 0, 0.00066, 0.86, 25823.926, 0.2, 24, 0, 0.00065, 2.52, 8170.957, 1.5, 25, 0, 0.00063, 0.18,
|
||||
8322.132, -0.3, 0, 0, 0.00060, 5.84, 8326.062, 1.5, 25, 0, 0.00060, 5.15, 8331.321, 1.5, 25, 0, 0.00060, 2.18,
|
||||
8486.426, 1.5, 25, 0, 0.00058, 2.30, -1.731, -4, -44, 0, 0.00058, 5.43, 14357.138, -2, -16, 0, 0.00057, 3.09,
|
||||
8294.910, 2, 29, 0, 0.00057, 4.67, -8362.473, -1, -21, 0, 0.00056, 4.15, 16833.151, -1, 0, 0, 0.00054, 1.93,
|
||||
7056.329, -2, -19, 0, 0.00054, 5.27, 8315.574, -2, -19, 0, 0.00052, 5.6, 8311.418, -2, -19, 0, 0.00052, 2.7,
|
||||
-77.552, 0, 0, 0, 0.00051, 4.3, 7230.984, 2, 25, 0, 0.00050, 0.4, -0.508, 0, 0, 0, 0.00049, 5.4, 7211.433, -2,
|
||||
-19, 0, 0.00049, 4.4, 7216.693, -2, -19, 0, 0.00049, 4.3, 16864.631, 0, 24, 0, 0.00049, 2.2, 16869.234, -3,
|
||||
-26, 0, 0.00047, 6.1, 627.596, 0, 0, 0, 0.00047, 5.0, 12.619, 1, 7, 0, 0.00045, 4.9, -8815.018, -5, -69, 0,
|
||||
0.00044, 1.6, 62.133, -2, -19, 0, 0.00042, 2.9, -13.118, -4, -44, 0, 0.00042, 4.1, -119.445, 0, 0, 0, 0.00041,
|
||||
4.3, 22756.817, -3, -13, 0, 0.00041, 3.6, 8288.877, 2, 25, 0, 0.00040, 0.5, 6663.308, -2, -19, 0, 0.00040, 1.1,
|
||||
8368.506, 2, 25, 0, 0.00039, 4.1, 6443.786, 2, 25, 0, 0.00039, 3.1, 16657.383, 3, 50, 0, 0.00038, 0.1,
|
||||
16657.031, 3, 50, 0, 0.00038, 3.0, 16657.735, 3, 50, 0, 0.00038, 4.6, 23942.433, -1, 9, 0, 0.00037, 4.3,
|
||||
15385.020, -1, 6, 0, 0.00037, 5.0, 548.678, 0, 0, 0, 0.00036, 1.8, 7213.352, -2, -19, 0, 0.00036, 1.7,
|
||||
7214.774, -2, -19, 0, 0.00035, 1.1, 7777.936, 2, 25, 0, 0.00035, 1.6, -8.860, 0, 0, 0, 0.00035, 4.4, 23869.145,
|
||||
2, 56, 0, 0.00035, 2.0, 6691.693, -2, -19, 0, 0.00034, 1.3, -1185.616, -2, -22, 0, 0.00034, 2.2, 23873.747, -1,
|
||||
6, 0, 0.00033, 2.0, -235.287, 0, 0, 0, 0.00033, 3.1, 17913.987, 3, 50, 0, 0.00033, 1.0, 8351.233, -2, -19, 0),
|
||||
(0.004870, 4.6693, 628.30196, -0.027, 0, -0.01, 0.002280, 2.6746, -2.30120, 1.523, 25, -0.12, 0.001500, 3.372,
|
||||
6585.76091, -2.16, -19, 0.1, 0.001200, 5.728, 14914.45233, -0.64, 6, 0, 0.001080, 3.969, 7700.38947, 1.55, 25,
|
||||
-0.1, 0.000800, 0.742, 8956.99338, 1.50, 25, -0.1, 0.000254, 6.002, 0.3286, 1.52, 25, -0.1, 0.000210, 0.144,
|
||||
7842.3648, -2.21, -19, 0, 0.000180, 2.500, 16171.0562, -0.7, 6, 0, 0.000130, 0.44, 8399.6791, -0.4, 3, 0,
|
||||
0.000126, 5.03, 8326.3902, 3.0, 50, 0, 0.000120, 5.77, 14286.1504, -0.6, 6, 0, 0.000118, 5.96, 8330.9926, 0, 0,
|
||||
0, 0.000110, 1.80, 23243.1438, 0.9, 31, 0, 0.000110, 3.42, 5957.4590, -2.1, -19, 0, 0.000110, 4.63, 1256.6039,
|
||||
-0.1, 0, 0, 0.000099, 4.70, -0.7113, 0, 0, 0, 0.000070, 0.04, 16029.0809, 3.1, 50, 0, 0.000070, 5.14,
|
||||
8328.3391, 1.5, 25, 0, 0.000070, 5.85, 8329.0437, 1.5, 25, 0, 0.000060, 1.02, -1742.9305, -3.7, -44, 0,
|
||||
0.000060, 3.10, 17285.6848, 3.0, 50, 0, 0.000054, 5.69, -0.352, 0, 0, 0, 0.000043, 0.52, 15.542, 0, 0, 0,
|
||||
0.000041, 2.03, 2.630, 0, 0, 0, 0.000040, 0.10, 8470.667, -2.2, -19, 0, 0.000040, 4.01, 7072.088, 1.6, 25, 0,
|
||||
0.000036, 2.93, -8.860, -0.3, 0, 0, 0.000030, 1.20, 22128.515, -2.8, -13, 0, 0.000030, 2.54, 15542.754, -0.7,
|
||||
6, 0, 0.000027, 4.43, 7211.762, -0.7, 6, 0, 0.000026, 0.51, 15540.453, 0.9, 31, 0, 0.000026, 1.44, 15545.055,
|
||||
-2.2, -19, 0, 0.000025, 5.37, 7216.364, -3.7, -44, 0),
|
||||
(0.00001200, 1.041, -2.3012, 1.52, 25, -0.1, 0.00000170, 0.31, -0.711, 0, 0, 0)
|
||||
)
|
||||
__QI_KB = (
|
||||
1640650.479938, 15.21842500, # -221-11-09 h=0.01709 古历·秦汉
|
||||
1642476.703182, 15.21874996, # -216-11-09 h=0.01557 古历·秦汉
|
||||
1683430.515601, 15.218750011, # -104-12-25 h=0.01560 汉书·律历志(太初历)平气平朔 回归年=365.25000
|
||||
1752157.640664, 15.218749978, # 85-02-23 h=0.01559 后汉书·律历志(四分历) 回归年=365.25000
|
||||
1807675.003759, 15.218620279, # 237-02-22 h=0.00010 晋书·律历志(景初历) 回归年=365.24689
|
||||
1883627.765182, 15.218612292, # 445-02-03 h=0.00026 宋书·律历志(何承天元嘉历) 回归年=365.24670
|
||||
1907369.128100, 15.218449176, # 510-02-03 h=0.00027 宋书·律历志(祖冲之大明历) 回归年=365.24278
|
||||
1936603.140413, 15.218425000, # 590-02-17 h=0.00149 随书·律历志(开皇历) 回归年=365.24220
|
||||
1939145.524180, 15.218466998, # 597-02-03 h=0.00121 随书·律历志(大业历) 回归年=365.24321
|
||||
1947180.798300, 15.218524844, # 619-02-03 h=0.00052 新唐书·历志(戊寅元历)平气定朔 回归年=365.24460
|
||||
1964362.041824, 15.218533526, # 666-02-17 h=0.00059 新唐书·历志(麟德历) 回归年=365.24480
|
||||
1987372.340971, 15.218513908, # 729-02-16 h=0.00096 新唐书·历志(大衍历,至德历) 回归年=365.24433
|
||||
1999653.819126, 15.218530782, # 762-10-03 h=0.00093 新唐书·历志(五纪历) 回归年=365.24474
|
||||
2007445.469786, 15.218535181, # 784-02-01 h=0.00059 新唐书·历志(正元历,观象历) 回归年=365.24484
|
||||
2021324.917146, 15.218526248, # 822-02-01 h=0.00022 新唐书·历志(宣明历) 回归年=365.24463
|
||||
2047257.232342, 15.218519654, # 893-01-31 h=0.00015 新唐书·历志(崇玄历) 回归年=365.24447
|
||||
2070282.898213, 15.218425000, # 956-02-16 h=0.00149 旧五代·历志(钦天历) 回归年=365.24220
|
||||
2073204.872850, 15.218515221, # 964-02-16 h=0.00166 宋史·律历志(应天历) 回归年=365.24437
|
||||
2080144.500926, 15.218530782, # 983-02-16 h=0.00093 宋史·律历志(乾元历) 回归年=365.24474
|
||||
2086703.688963, 15.218523776, # 1001-01-31 h=0.00067 宋史·律历志(仪天历,崇天历) 回归年=365.24457
|
||||
2110033.182763, 15.218425000, # 1064-12-15 h=0.00669 宋史·律历志(明天历) 回归年=365.24220
|
||||
2111190.300888, 15.218425000, # 1068-02-15 h=0.00149 宋史·律历志(崇天历) 回归年=365.24220
|
||||
2113731.271005, 15.218515671, # 1075-01-30 h=0.00038 李锐补修(奉元历) 回归年=365.24438
|
||||
2120670.840263, 15.218425000, # 1094-01-30 h=0.00149 宋史·律历志 回归年=365.24220
|
||||
2123973.309063, 15.218425000, # 1103-02-14 h=0.00669 李锐补修(占天历) 回归年=365.24220
|
||||
2125068.997336, 15.218477932, # 1106-02-14 h=0.00056 宋史·律历志(纪元历) 回归年=365.24347
|
||||
2136026.312633, 15.218472436, # 1136-02-14 h=0.00088 宋史·律历志(统元历,乾道历,淳熙历) 回归年=365.24334
|
||||
2156099.495538, 15.218425000, # 1191-01-29 h=0.00149 宋史·律历志(会元历) 回归年=365.24220
|
||||
2159021.324663, 15.218425000, # 1199-01-29 h=0.00149 宋史·律历志(统天历) 回归年=365.24220
|
||||
2162308.575254, 15.218461742, # 1208-01-30 h=0.00146 宋史·律历志(开禧历) 回归年=365.24308
|
||||
2178485.706538, 15.218425000, # 1252-05-15 h=0.04606 淳祐历 回归年=365.24220
|
||||
2178759.662849, 15.218445786, # 1253-02-13 h=0.00231 会天历 回归年=365.24270
|
||||
2185334.020800, 15.218425000, # 1271-02-13 h=0.00520 宋史·律历志(成天历) 回归年=365.24220
|
||||
2187525.481425, 15.218425000, # 1277-02-12 h=0.00520 本天历 回归年=365.24220
|
||||
2188621.191481, 15.218437494, # 1280-02-13 h=0.00015 元史·历志(郭守敬授时历) 回归年=365.24250
|
||||
2322147.76 # 1645-09-21
|
||||
)
|
||||
# 1645-09-23开始7567个节气修正表
|
||||
__QB = ''
|
||||
__SHUO_KB = (
|
||||
1457698.231017, 29.53067166, 1546082.512234, 29.53085106, 1640640.735300, 29.53060000, 1642472.151543,
|
||||
29.53085439,
|
||||
1683430.509300, 29.53086148, 1752148.041079, 29.53085097, 1807665.420323, 29.53059851, 1883618.114100,
|
||||
29.53060000,
|
||||
1907360.704700, 29.53060000, 1936596.224900, 29.53060000, 1939135.675300, 29.53060000, 1947168.00)
|
||||
# 619-01-21开始16598个朔日修正表 d0=1947168
|
||||
__SB = ''
|
||||
|
||||
@staticmethod
|
||||
def __decode(s: str) -> str:
|
||||
o = '0000000000'
|
||||
o2 = o + o
|
||||
s = s.replace('J', '00')
|
||||
s = s.replace('I', '000')
|
||||
s = s.replace('H', '0000')
|
||||
s = s.replace('G', '00000')
|
||||
s = s.replace('t', '02')
|
||||
s = s.replace('s', '002')
|
||||
s = s.replace('r', '0002')
|
||||
s = s.replace('q', '00002')
|
||||
s = s.replace('p', '000002')
|
||||
s = s.replace('o', '0000002')
|
||||
s = s.replace('n', '00000002')
|
||||
s = s.replace('m', '000000002')
|
||||
s = s.replace('l', '0000000002')
|
||||
s = s.replace('k', '01')
|
||||
s = s.replace('j', '0101')
|
||||
s = s.replace('i', '001')
|
||||
s = s.replace('h', '001001')
|
||||
s = s.replace('g', '0001')
|
||||
s = s.replace('f', '00001')
|
||||
s = s.replace('e', '000001')
|
||||
s = s.replace('d', '0000001')
|
||||
s = s.replace('c', '00000001')
|
||||
s = s.replace('b', '000000001')
|
||||
s = s.replace('a', '0000000001')
|
||||
s = s.replace('A', o2 + o2 + o2)
|
||||
s = s.replace('B', o2 + o2 + o)
|
||||
s = s.replace('C', o2 + o2)
|
||||
s = s.replace('D', o2 + o)
|
||||
s = s.replace('E', o2)
|
||||
s = s.replace('F', o)
|
||||
return s
|
||||
|
||||
@staticmethod
|
||||
def nutation_lon2(t: float) -> float:
|
||||
a: float = -1.742 * t
|
||||
t2: float = t * t
|
||||
dl: float = 0
|
||||
for i in range(0, ShouXingUtil.__NUT_B.__len__(), 5):
|
||||
dl += (ShouXingUtil.__NUT_B[i + 3] + a) * sin(
|
||||
ShouXingUtil.__NUT_B[i] + ShouXingUtil.__NUT_B[i + 1] * t + ShouXingUtil.__NUT_B[i + 2] * t2)
|
||||
a = 0
|
||||
return dl / 100 / ShouXingUtil.SECOND_PER_RAD
|
||||
|
||||
@staticmethod
|
||||
def e_lon(t: float, n: int) -> float:
|
||||
t /= 10
|
||||
v: float = 0
|
||||
tn: float = 1
|
||||
pn: int = 1
|
||||
m0: float = ShouXingUtil.__XL0[pn + 1] - ShouXingUtil.__XL0[pn]
|
||||
for i in range(0, 6):
|
||||
n1 = int(ShouXingUtil.__XL0[pn + i])
|
||||
n2 = int(ShouXingUtil.__XL0[pn + 1 + i])
|
||||
n0 = n2 - n1
|
||||
if n0 == 0:
|
||||
continue
|
||||
if n < 0:
|
||||
m = n2
|
||||
else:
|
||||
m = int((3 * n * n0 / m0 + 0.5) + n1)
|
||||
if i != 0:
|
||||
m += 3
|
||||
if m > n2:
|
||||
m = n2
|
||||
c = 0
|
||||
for j in range(n1, m, 3):
|
||||
c += ShouXingUtil.__XL0[j] * cos(ShouXingUtil.__XL0[j + 1] + t * ShouXingUtil.__XL0[j + 2])
|
||||
v += c * tn
|
||||
tn *= t
|
||||
v /= ShouXingUtil.__XL0[0]
|
||||
t2 = t * t
|
||||
t3 = t2 * t
|
||||
return v + (-0.0728 - 2.7702 * t - 1.1019 * t2 - 0.0996 * t3) / ShouXingUtil.SECOND_PER_RAD
|
||||
|
||||
@staticmethod
|
||||
def m_lon(t: float, n: int) -> float:
|
||||
ob = ShouXingUtil.__XL1
|
||||
obl = len(ob[0])
|
||||
tn = 1
|
||||
v = 0
|
||||
t2 = t * t
|
||||
t3 = t2 * t
|
||||
t4 = t3 * t
|
||||
t5 = t4 * t
|
||||
tx = t - 10
|
||||
v += (3.81034409 + 8399.684730072 * t - 3.319e-05 * t2 + 3.11e-08 * t3 - 2.033e-10 * t4) * ShouXingUtil.SECOND_PER_RAD
|
||||
v += 5028.792262 * t + 1.1124406 * t2 + 0.00007699 * t3 - 0.000023479 * t4 - 0.0000000178 * t5
|
||||
if tx > 0:
|
||||
v += -0.866 + 1.43 * tx + 0.054 * tx * tx
|
||||
t2 /= 1e4
|
||||
t3 /= 1e8
|
||||
t4 /= 1e8
|
||||
|
||||
n *= 6
|
||||
if n < 0:
|
||||
n = obl
|
||||
for i in range(len(ob)):
|
||||
f = ob[i]
|
||||
size = len(f)
|
||||
m = int(n * size / obl + 0.5)
|
||||
if i > 0:
|
||||
m += 6
|
||||
if m >= size:
|
||||
m = size
|
||||
c = 0
|
||||
for j in range(0, m, 6):
|
||||
c += f[j] * cos(f[j + 1] + t * f[j + 2] + t2 * f[j + 3] + t3 * f[j + 4] + t4 * f[j + 5])
|
||||
v += c * tn
|
||||
tn *= t
|
||||
return v / ShouXingUtil.SECOND_PER_RAD
|
||||
|
||||
@staticmethod
|
||||
def gxc_sun_lon(t: float) -> float:
|
||||
return -20.49552 * (1 + (0.016708634 - 0.000042037 * t - 0.0000001267 * t * t) * cos(-0.043126 + 628.301955 * t - 0.000002732 * t * t)) / ShouXingUtil.SECOND_PER_RAD
|
||||
|
||||
@staticmethod
|
||||
def ev(t: float) -> float:
|
||||
f = 628.307585 * t
|
||||
return 628.332 + 21 * sin(1.527 + f) + 0.44 * sin(1.48 + f * 2) + 0.129 * sin(5.82 + f) * t + 0.00055 * sin(4.21 + f) * t * t
|
||||
|
||||
@staticmethod
|
||||
def mv(t: float) -> float:
|
||||
v = 8399.71 - 914 * sin(0.7848 + 8328.691425 * t + 0.0001523 * t * t)
|
||||
return v - (179 * sin(2.543 + 15542.7543 * t) + 160 * sin(0.1874 + 7214.0629 * t) + 62 * sin(3.14 + 16657.3828 * t) + 34 * sin(4.827 + 16866.9323 * t) + 22 * sin(4.9 + 23871.4457 * t) + 12 * sin(2.59 + 14914.4523 * t) + 7 * sin(0.23 + 6585.7609 * t) + 5 * sin(0.9 + 25195.624 * t) + 5 * sin(2.32 - 7700.3895 * t) + 5 * sin(3.88 + 8956.9934 * t) + 5 * sin(0.49 + 7771.3771 * t))
|
||||
|
||||
@staticmethod
|
||||
def sa_lon(t: float, n: int) -> float:
|
||||
return ShouXingUtil.e_lon(t, n) + ShouXingUtil.nutation_lon2(t) + ShouXingUtil.gxc_sun_lon(t) + ShouXingUtil.PI
|
||||
|
||||
@staticmethod
|
||||
def dt_ext(y: float, jsd: int) -> float:
|
||||
dy = (y - 1820) * 1.0 / 100
|
||||
return - 20 + jsd * dy * dy
|
||||
|
||||
@staticmethod
|
||||
def dt_calc(y: float) -> float:
|
||||
size = len(ShouXingUtil.__DT_AT)
|
||||
y0 = ShouXingUtil.__DT_AT[size - 2]
|
||||
t0 = ShouXingUtil.__DT_AT[size - 1]
|
||||
if y >= y0:
|
||||
jsd: int = 31
|
||||
if y > y0 + 100:
|
||||
return ShouXingUtil.dt_ext(y, jsd)
|
||||
v = ShouXingUtil.dt_ext(y, jsd)
|
||||
dv = ShouXingUtil.dt_ext(y0, jsd) - t0
|
||||
return v - dv * (y0 + 100 - y) / 100
|
||||
i = 0
|
||||
for i in range(0, size, 5):
|
||||
if y < ShouXingUtil.__DT_AT[i + 5]:
|
||||
break
|
||||
t1 = (y - ShouXingUtil.__DT_AT[i]) / (ShouXingUtil.__DT_AT[i + 5] - ShouXingUtil.__DT_AT[i]) * 10
|
||||
t2 = t1 * t1
|
||||
t3 = t2 * t1
|
||||
return ShouXingUtil.__DT_AT[i + 1] + ShouXingUtil.__DT_AT[i + 2] * t1 + ShouXingUtil.__DT_AT[i + 3] * t2 + ShouXingUtil.__DT_AT[i + 4] * t3
|
||||
|
||||
@staticmethod
|
||||
def dt_t(t: float) -> float:
|
||||
return ShouXingUtil.dt_calc(t / 365.2425 + 2000) / ShouXingUtil.SECOND_PER_DAY
|
||||
|
||||
@staticmethod
|
||||
def sa_lon_t(w: float) -> float:
|
||||
v = 628.3319653318
|
||||
t = (w - 1.75347 - ShouXingUtil.PI) / v
|
||||
v = ShouXingUtil.ev(t)
|
||||
t += (w - ShouXingUtil.sa_lon(t, 10)) / v
|
||||
v = ShouXingUtil.ev(t)
|
||||
return t + (w - ShouXingUtil.sa_lon(t, -1)) / v
|
||||
|
||||
@staticmethod
|
||||
def msa_lon(t: float, mn: int, sn: int) -> float:
|
||||
return ShouXingUtil.m_lon(t, mn) + (-3.4E-6) - (ShouXingUtil.e_lon(t, sn) + ShouXingUtil.gxc_sun_lon(t) + ShouXingUtil.PI)
|
||||
|
||||
@staticmethod
|
||||
def msa_lon_t(w: float) -> float:
|
||||
v = 7771.37714500204
|
||||
t = (w + 1.08472) / v
|
||||
t += (w - ShouXingUtil.msa_lon(t, 3, 3)) / v
|
||||
v = ShouXingUtil.mv(t) - ShouXingUtil.ev(t)
|
||||
t += (w - ShouXingUtil.msa_lon(t, 20, 10)) / v
|
||||
return t + (w - ShouXingUtil.msa_lon(t, -1, 60)) / v
|
||||
|
||||
@staticmethod
|
||||
def sa_lon_t2(w: float) -> float:
|
||||
v = 628.3319653318
|
||||
t = (w - 1.75347 - ShouXingUtil.PI) / v
|
||||
t -= (0.000005297 * t * t + 0.0334166 * cos(4.669257 + 628.307585 * t) + 0.0002061 * cos(2.67823 + 628.307585 * t) * t) / v
|
||||
return t + (w - ShouXingUtil.e_lon(t, 8) - ShouXingUtil.PI + (20.5 + 17.2 * sin(2.1824 - 33.75705 * t)) / ShouXingUtil.SECOND_PER_RAD) / v
|
||||
|
||||
@staticmethod
|
||||
def msa_lon_t2(w: float) -> float:
|
||||
v = 7771.37714500204
|
||||
t = (w + 1.08472) / v
|
||||
t2 = t * t
|
||||
t -= (-0.00003309 * t2 + 0.10976 * cos(0.784758 + 8328.6914246 * t + 0.000152292 * t2) + 0.02224 * cos(0.18740 + 7214.0628654 * t - 0.00021848 * t2) - 0.03342 * cos(4.669257 + 628.307585 * t)) / v
|
||||
t2 = t * t
|
||||
n = ShouXingUtil.m_lon(t, 20) - (4.8950632 + 628.3319653318 * t + 0.000005297 * t2 + 0.0334166 * cos(4.669257 + 628.307585 * t) + 0.0002061 * cos(2.67823 + 628.307585 * t) * t + 0.000349 * cos(4.6261 + 1256.61517 * t) - 20.5 / ShouXingUtil.SECOND_PER_RAD)
|
||||
return t + (w - n) / (7771.38 - 914 * sin(0.7848 + 8328.691425 * t + 0.0001523 * t2) - 179 * sin(2.543 + 15542.7543 * t) - 160 * sin(0.1874 + 7214.0629 * t))
|
||||
|
||||
@staticmethod
|
||||
def qi_high(w: float) -> float:
|
||||
t = ShouXingUtil.sa_lon_t2(w) * 36525
|
||||
t = t - ShouXingUtil.dt_t(t) + ShouXingUtil.ONE_THIRD
|
||||
v = ((t + 0.5) % 1) * ShouXingUtil.SECOND_PER_DAY
|
||||
if v < 1200 or v > ShouXingUtil.SECOND_PER_DAY - 1200:
|
||||
t = ShouXingUtil.sa_lon_t(w) * 36525 - ShouXingUtil.dt_t(t) + ShouXingUtil.ONE_THIRD
|
||||
return t
|
||||
|
||||
@staticmethod
|
||||
def qi_low(w: float) -> float:
|
||||
v = 628.3319653318
|
||||
t = (w - 4.895062166) / v
|
||||
t -= (53 * t * t + 334116 * cos(4.67 + 628.307585 * t) + 2061 * cos(2.678 + 628.3076 * t) * t) / v / 10000000
|
||||
n = 48950621.66 + 6283319653.318 * t + 53 * t * t + 334166 * cos(4.669257 + 628.307585 * t) + 3489 * cos(4.6261 + 1256.61517 * t) + 2060.6 * cos(2.67823 + 628.307585 * t) * t - 994 - 834 * sin(2.1824 - 33.75705 * t)
|
||||
t -= (n / 10000000 - w) / 628.332 + (32 * (t + 1.8) * (t + 1.8) - 20) / ShouXingUtil.SECOND_PER_DAY / 36525
|
||||
return t * 36525 + ShouXingUtil.ONE_THIRD
|
||||
|
||||
@staticmethod
|
||||
def shuo_high(w: float) -> float:
|
||||
t = ShouXingUtil.msa_lon_t2(w) * 36525
|
||||
t = t - ShouXingUtil.dt_t(t) + ShouXingUtil.ONE_THIRD
|
||||
v = ((t + 0.5) % 1) * ShouXingUtil.SECOND_PER_DAY
|
||||
if v < 1800 or v > ShouXingUtil.SECOND_PER_DAY - 1800:
|
||||
t = ShouXingUtil.msa_lon_t(w) * 36525 - ShouXingUtil.dt_t(t) + ShouXingUtil.ONE_THIRD
|
||||
return t
|
||||
|
||||
@staticmethod
|
||||
def shuo_low(w: float) -> float:
|
||||
v = 7771.37714500204
|
||||
t = (w + 1.08472) / v
|
||||
t -= (-0.0000331 * t * t + 0.10976 * cos(0.785 + 8328.6914 * t) + 0.02224 * cos(0.187 + 7214.0629 * t) - 0.03342 * cos(4.669 + 628.3076 * t)) / v + (32 * (t + 1.8) * (t + 1.8) - 20) / ShouXingUtil.SECOND_PER_DAY / 36525
|
||||
return t * 36525 + ShouXingUtil.ONE_THIRD
|
||||
|
||||
@staticmethod
|
||||
def calc_shuo(jd: float) -> int:
|
||||
if len(ShouXingUtil.__SB) < 1:
|
||||
ShouXingUtil.__SB = ShouXingUtil.__decode('EqoFscDcrFpmEsF2DfFideFelFpFfFfFiaipqti1ksttikptikqckstekqttgkqttgkqteksttikptikq2fjstgjqttjkqttgkqtekstfkptikq2tijstgjiFkirFsAeACoFsiDaDiADc1AFbBfgdfikijFifegF1FhaikgFag1E2btaieeibggiffdeigFfqDfaiBkF1kEaikhkigeidhhdiegcFfakF1ggkidbiaedksaFffckekidhhdhdikcikiakicjF1deedFhFccgicdekgiFbiaikcfi1kbFibefgEgFdcFkFeFkdcfkF1kfkcickEiFkDacFiEfbiaejcFfffkhkdgkaiei1ehigikhdFikfckF1dhhdikcfgjikhfjicjicgiehdikcikggcifgiejF1jkieFhegikggcikFegiegkfjebhigikggcikdgkaFkijcfkcikfkcifikiggkaeeigefkcdfcfkhkdgkegieidhijcFfakhfgeidieidiegikhfkfckfcjbdehdikggikgkfkicjicjF1dbidikFiggcifgiejkiegkigcdiegfggcikdbgfgefjF1kfegikggcikdgFkeeijcfkcikfkekcikdgkabhkFikaffcfkhkdgkegbiaekfkiakicjhfgqdq2fkiakgkfkhfkfcjiekgFebicggbedF1jikejbbbiakgbgkacgiejkijjgigfiakggfggcibFifjefjF1kfekdgjcibFeFkijcfkfhkfkeaieigekgbhkfikidfcjeaibgekgdkiffiffkiakF1jhbakgdki1dj1ikfkicjicjieeFkgdkicggkighdF1jfgkgfgbdkicggfggkidFkiekgijkeigfiskiggfaidheigF1jekijcikickiggkidhhdbgcfkFikikhkigeidieFikggikhkffaffijhidhhakgdkhkijF1kiakF1kfheakgdkifiggkigicjiejkieedikgdfcggkigieeiejfgkgkigbgikicggkiaideeijkefjeijikhkiggkiaidheigcikaikffikijgkiahi1hhdikgjfifaakekighie1hiaikggikhkffakicjhiahaikggikhkijF1kfejfeFhidikggiffiggkigicjiekgieeigikggiffiggkidheigkgfjkeigiegikifiggkidhedeijcfkFikikhkiggkidhh1ehigcikaffkhkiggkidhh1hhigikekfiFkFikcidhh1hitcikggikhkfkicjicghiediaikggikhkijbjfejfeFhaikggifikiggkigiejkikgkgieeigikggiffiggkigieeigekijcijikggifikiggkideedeijkefkfckikhkiggkidhh1ehijcikaffkhkiggkidhh1hhigikhkikFikfckcidhh1hiaikgjikhfjicjicgiehdikcikggifikigiejfejkieFhegikggifikiggfghigkfjeijkhigikggifikiggkigieeijcijcikfksikifikiggkidehdeijcfdckikhkiggkhghh1ehijikifffffkhsFngErD1pAfBoDd1BlEtFqA2AqoEpDqElAEsEeB2BmADlDkqBtC1FnEpDqnEmFsFsAFnllBbFmDsDiCtDmAB2BmtCgpEplCpAEiBiEoFqFtEqsDcCnFtADnFlEgdkEgmEtEsCtDmADqFtAFrAtEcCqAE1BoFqC1F1DrFtBmFtAC2ACnFaoCgADcADcCcFfoFtDlAFgmFqBq2bpEoAEmkqnEeCtAE1bAEqgDfFfCrgEcBrACfAAABqAAB1AAClEnFeCtCgAADqDoBmtAAACbFiAAADsEtBqAB2FsDqpFqEmFsCeDtFlCeDtoEpClEqAAFrAFoCgFmFsFqEnAEcCqFeCtFtEnAEeFtAAEkFnErAABbFkADnAAeCtFeAfBoAEpFtAABtFqAApDcCGJ')
|
||||
size = len(ShouXingUtil.__SHUO_KB)
|
||||
d = 0
|
||||
pc = 14
|
||||
i = 0
|
||||
jd += ShouXingUtil.J2000
|
||||
f1 = ShouXingUtil.__SHUO_KB[0] - pc
|
||||
f2 = ShouXingUtil.__SHUO_KB[size - 1] - pc
|
||||
f3 = 2436935
|
||||
if jd < f1 or jd >= f3:
|
||||
d = floor(ShouXingUtil.shuo_high(floor((jd + pc - 2451551) / 29.5306) * ShouXingUtil.PI * 2) + 0.5)
|
||||
elif f1 <= jd < f2:
|
||||
for i in range(0, size, 2):
|
||||
if jd + pc < ShouXingUtil.__SHUO_KB[i + 2]:
|
||||
break
|
||||
d = ShouXingUtil.__SHUO_KB[i] + ShouXingUtil.__SHUO_KB[i + 1] * floor((jd + pc - ShouXingUtil.__SHUO_KB[i]) / ShouXingUtil.__SHUO_KB[i + 1])
|
||||
d = floor(d + 0.5)
|
||||
if d == 1683460:
|
||||
d += 1
|
||||
d -= ShouXingUtil.J2000
|
||||
elif f2 <= jd < f3:
|
||||
d = floor(ShouXingUtil.shuo_low(floor((jd + pc - 2451551) / 29.5306) * ShouXingUtil.PI * 2) + 0.5)
|
||||
index = floor((jd - f2) / 29.5306)
|
||||
n = ShouXingUtil.__SB[index:index + 1]
|
||||
if '1' == n:
|
||||
d += 1
|
||||
elif '2' == n:
|
||||
d -= 1
|
||||
return d
|
||||
|
||||
@staticmethod
|
||||
def calc_qi(jd: float) -> int:
|
||||
if len(ShouXingUtil.__QB) < 1:
|
||||
ShouXingUtil.__QB = ShouXingUtil.__decode('FrcFs22AFsckF2tsDtFqEtF1posFdFgiFseFtmelpsEfhkF2anmelpFlF1ikrotcnEqEq2FfqmcDsrFor22FgFrcgDscFs22FgEeFtE2sfFs22sCoEsaF2tsD1FpeE2eFsssEciFsFnmelpFcFhkF2tcnEqEpFgkrotcnEqrEtFermcDsrE222FgBmcmr22DaEfnaF222sD1FpeForeF2tssEfiFpEoeFssD1iFstEqFppDgFstcnEqEpFg11FscnEqrAoAF2ClAEsDmDtCtBaDlAFbAEpAAAAAD2FgBiBqoBbnBaBoAAAAAAAEgDqAdBqAFrBaBoACdAAf1AACgAAAeBbCamDgEifAE2AABa1C1BgFdiAAACoCeE1ADiEifDaAEqAAFe1AcFbcAAAAAF1iFaAAACpACmFmAAAAAAAACrDaAAADG0')
|
||||
size = len(ShouXingUtil.__QI_KB)
|
||||
d = 0
|
||||
pc = 7
|
||||
i = 0
|
||||
jd += ShouXingUtil.J2000
|
||||
f1 = ShouXingUtil.__QI_KB[0] - pc
|
||||
f2 = ShouXingUtil.__QI_KB[size - 1] - pc
|
||||
f3 = 2436935
|
||||
if jd < f1 or jd >= f3:
|
||||
# 2451259是1999.3.21,太阳视黄经为0,春分 定气计算
|
||||
d = floor(ShouXingUtil.qi_high(floor((jd + pc - 2451259) / 365.2422 * 24) * ShouXingUtil.PI / 12) + 0.5)
|
||||
elif f1 <= jd < f2:
|
||||
for i in range(0, size, 2):
|
||||
if jd + pc < ShouXingUtil.__QI_KB[i + 2]:
|
||||
break
|
||||
d = ShouXingUtil.__QI_KB[i] + ShouXingUtil.__QI_KB[i + 1] * floor((jd + pc - ShouXingUtil.__QI_KB[i]) / ShouXingUtil.__QI_KB[i + 1])
|
||||
d = floor(d + 0.5)
|
||||
if d == 1683460:
|
||||
d += 1
|
||||
d -= ShouXingUtil.J2000
|
||||
elif f2 <= jd < f3:
|
||||
d = floor(ShouXingUtil.qi_low(floor((jd + pc - 2451259) / 365.2422 * 24) * ShouXingUtil.PI / 12) + 0.5)
|
||||
# 找定气修正值
|
||||
index = floor((jd - f2) / 365.2422 * 24)
|
||||
n = ShouXingUtil.__QB[index:index + 1]
|
||||
if '1' == n:
|
||||
d += 1
|
||||
elif '2' == n:
|
||||
d -= 1
|
||||
return d
|
||||
|
||||
@staticmethod
|
||||
def qi_accurate(w: float) -> float:
|
||||
t = ShouXingUtil.sa_lon_t(w) * 36525
|
||||
return t - ShouXingUtil.dt_t(t) + ShouXingUtil.ONE_THIRD
|
||||
|
||||
@staticmethod
|
||||
def qi_accurate2(jd: float) -> float:
|
||||
d: float = ShouXingUtil.PI / 12
|
||||
w: float = floor((jd + 293) / 365.2422 * 24) * d
|
||||
a: float = ShouXingUtil.qi_accurate(w)
|
||||
if a - jd > 5:
|
||||
return ShouXingUtil.qi_accurate(w - d)
|
||||
if a - jd < -5:
|
||||
return ShouXingUtil.qi_accurate(w + d)
|
||||
return a
|
||||
Reference in New Issue
Block a user