tradecatlabs's picture
deploy FateCat HF Space free web workbench
acb2cec verified
Raw
History Blame Contribute Delete
48.7 kB
# -*- coding: utf-8 -*-
from . import Solar, NineStar, EightChar, JieQi, ShuJiu, Fu, LunarTime
from .util import LunarUtil, SolarUtil
class Lunar:
"""
阴历日期
"""
JIE_QI = ("冬至", "小寒", "大寒", "立春", "雨水", "惊蛰", "春分", "清明", "谷雨", "立夏", "小满", "芒种", "夏至", "小暑", "大暑", "立秋", "处暑", "白露", "秋分", "寒露", "霜降", "立冬", "小雪", "大雪")
JIE_QI_IN_USE = ("DA_XUE", "冬至", "小寒", "大寒", "立春", "雨水", "惊蛰", "春分", "清明", "谷雨", "立夏", "小满", "芒种", "夏至", "小暑", "大暑", "立秋", "处暑", "白露", "秋分", "寒露", "霜降", "立冬", "小雪", "大雪", "DONG_ZHI", "XIAO_HAN", "DA_HAN", "LI_CHUN", "YU_SHUI", "JING_ZHE")
def __init__(self, lunar_year: int, lunar_month: int, lunar_day: int, hour: int, minute: int, second: int):
from . import LunarYear
y = LunarYear.fromYear(lunar_year)
m = y.getMonth(lunar_month)
if m is None:
raise Exception("wrong lunar year %d month %d" % (lunar_year, lunar_month))
if lunar_day < 1:
raise Exception("lunar day must bigger than 0")
days = m.getDayCount()
if lunar_day > days:
raise Exception("only %d days in lunar year %d month %d" % (days, lunar_year, lunar_month))
self.__year = lunar_year
self.__month = lunar_month
self.__day = lunar_day
self.__hour = hour
self.__minute = minute
self.__second = second
self.__jieQi = {}
self.__jieQiList = []
self.__eightChar = None
noon = Solar.fromJulianDay(m.getFirstJulianDay() + lunar_day - 1)
self.__solar = Solar.fromYmdHms(noon.getYear(), noon.getMonth(), noon.getDay(), hour, minute, second)
if noon.getYear() != lunar_year:
y = LunarYear.fromYear(noon.getYear())
self.__compute(y)
def __compute(self, y):
self.__computeJieQi(y)
self.__computeYear()
self.__computeMonth()
self.__computeDay()
self.__computeTime()
self.__computeWeek()
def __computeJieQi(self, y):
julian_days = y.getJieQiJulianDays()
for i in range(0, len(Lunar.JIE_QI_IN_USE)):
name = Lunar.JIE_QI_IN_USE[i]
self.__jieQi[name] = Solar.fromJulianDay(julian_days[i])
self.__jieQiList.append(name)
def __computeYear(self):
# 以正月初一开始
offset = self.__year - 4
year_gan_index = offset % 10
year_zhi_index = offset % 12
if year_gan_index < 0:
year_gan_index += 10
if year_zhi_index < 0:
year_zhi_index += 12
# 以立春作为新一年的开始的干支纪年
g = year_gan_index
z = year_zhi_index
# 精确的干支纪年,以立春交接时刻为准
g_exact = year_gan_index
z_exact = year_zhi_index
solar_year = self.__solar.getYear()
solar_ymd = self.__solar.toYmd()
solar_ymd_hms = self.__solar.toYmdHms()
# 获取立春的阳历时刻
li_chun = self.__jieQi["立春"]
if li_chun.getYear() != solar_year:
li_chun = self.__jieQi["LI_CHUN"]
li_chun_ymd = li_chun.toYmd()
li_chun_ymd_hms = li_chun.toYmdHms()
# 阳历和阴历年份相同代表正月初一及以后
if self.__year == solar_year:
# 立春日期判断
if solar_ymd < li_chun_ymd:
g -= 1
z -= 1
# 立春交接时刻判断
if solar_ymd_hms < li_chun_ymd_hms:
g_exact -= 1
z_exact -= 1
elif self.__year < solar_year:
if solar_ymd >= li_chun_ymd:
g += 1
z += 1
if solar_ymd_hms >= li_chun_ymd_hms:
g_exact += 1
z_exact += 1
self.__yearGanIndex = year_gan_index
self.__yearZhiIndex = year_zhi_index
self.__yearGanIndexByLiChun = (g + 10 if g < 0 else g) % 10
self.__yearZhiIndexByLiChun = (z + 12 if z < 0 else z) % 12
self.__yearGanIndexExact = (g_exact + 10 if g_exact < 0 else g_exact) % 10
self.__yearZhiIndexExact = (z_exact + 12 if z_exact < 0 else z_exact) % 12
def __computeMonth(self):
ymd = self.__solar.toYmd()
time = self.__solar.toYmdHms()
size = len(Lunar.JIE_QI_IN_USE)
# 序号:大雪以前-3,大雪到小寒之间-2,小寒到立春之间-1,立春之后0
index = -3
start = None
for i in range(0, size, 2):
end = self.__jieQi[Lunar.JIE_QI_IN_USE[i]]
symd = ymd if start is None else start.toYmd()
if symd <= ymd < end.toYmd():
break
start = end
index += 1
# 干偏移值(以立春当天起算)
g_offset = (((self.__yearGanIndexByLiChun + (1 if index < 0 else 0)) % 5 + 1) * 2) % 10
self.__monthGanIndex = ((index + 10 if index < 0 else index) + g_offset) % 10
self.__monthZhiIndex = ((index + 12 if index < 0 else index) + LunarUtil.BASE_MONTH_ZHI_INDEX) % 12
index = -3
start = None
for i in range(0, size, 2):
end = self.__jieQi[Lunar.JIE_QI_IN_USE[i]]
stime = time if start is None else start.toYmdHms()
if stime <= time < end.toYmdHms():
break
start = end
index += 1
# 干偏移值(以立春交接时刻起算)
g_offset = (((self.__yearGanIndexExact + (1 if index < 0 else 0)) % 5 + 1) * 2) % 10
self.__monthGanIndexExact = ((index + 10 if index < 0 else index) + g_offset) % 10
self.__monthZhiIndexExact = ((index + 12 if index < 0 else index) + LunarUtil.BASE_MONTH_ZHI_INDEX) % 12
def __computeDay(self):
noon = Solar.fromYmdHms(self.__solar.getYear(), self.__solar.getMonth(), self.__solar.getDay(), 12, 0, 0)
offset = int(noon.getJulianDay()) - 11
day_gan_index = offset % 10
day_zhi_index = offset % 12
self.__dayGanIndex = day_gan_index
self.__dayZhiIndex = day_zhi_index
day_gan_exact = day_gan_index
day_zhi_exact = day_zhi_index
# 八字流派2,晚子时(夜子/子夜)日柱算当天
self.__dayGanIndexExact2 = day_gan_exact
self.__dayZhiIndexExact2 = day_zhi_exact
# 八字流派1,晚子时(夜子/子夜)日柱算明天
hm = ("0" if self.__hour < 10 else "") + str(self.__hour) + ":" + ("0" if self.__minute < 10 else "") + str(self.__minute)
if "23:00" <= hm <= "23:59":
day_gan_exact += 1
if day_gan_exact >= 10:
day_gan_exact -= 10
day_zhi_exact += 1
if day_zhi_exact >= 12:
day_zhi_exact -= 12
self.__dayGanIndexExact = day_gan_exact
self.__dayZhiIndexExact = day_zhi_exact
def __computeTime(self):
time_zhi_index = LunarUtil.getTimeZhiIndex(("0" if self.__hour < 10 else "") + str(self.__hour) + ":" + ("0" if self.__minute < 10 else "") + str(self.__minute))
self.__timeZhiIndex = time_zhi_index
self.__timeGanIndex = (self.__dayGanIndexExact % 5 * 2 + time_zhi_index) % 10
def __computeWeek(self):
self.__weekIndex = self.__solar.getWeek()
@staticmethod
def fromYmdHms(lunar_year, lunar_month, lunar_day, hour, minute, second):
return Lunar(lunar_year, lunar_month, lunar_day, hour, minute, second)
@staticmethod
def fromYmd(lunar_year, lunar_month, lunar_day):
return Lunar(lunar_year, lunar_month, lunar_day, 0, 0, 0)
@staticmethod
def fromDate(date):
return Lunar.fromSolar(Solar.fromDate(date))
@staticmethod
def fromSolar(solar):
from . import LunarYear
year = 0
month = 0
day = 0
ly = LunarYear.fromYear(solar.getYear())
for m in ly.getMonths():
days = solar.subtract(Solar.fromJulianDay(m.getFirstJulianDay()))
if days < m.getDayCount():
year = m.getYear()
month = m.getMonth()
day = days + 1
break
return Lunar(year, month, day, solar.getHour(), solar.getMinute(), solar.getSecond())
def getYear(self):
return self.__year
def getMonth(self):
return self.__month
def getDay(self):
return self.__day
def getHour(self):
return self.__hour
def getMinute(self):
return self.__minute
def getSecond(self):
return self.__second
def getSolar(self):
return self.__solar
def getYearGan(self):
return LunarUtil.GAN[self.__yearGanIndex + 1]
def getYearGanByLiChun(self):
return LunarUtil.GAN[self.__yearGanIndexByLiChun + 1]
def getYearGanExact(self):
return LunarUtil.GAN[self.__yearGanIndexExact + 1]
def getYearZhi(self):
return LunarUtil.ZHI[self.__yearZhiIndex + 1]
def getYearZhiByLiChun(self):
return LunarUtil.ZHI[self.__yearZhiIndexByLiChun + 1]
def getYearZhiExact(self):
return LunarUtil.ZHI[self.__yearZhiIndexExact + 1]
def getYearInGanZhi(self):
return "%s%s" % (self.getYearGan(), self.getYearZhi())
def getYearInGanZhiByLiChun(self):
return "%s%s" % (self.getYearGanByLiChun(), self.getYearZhiByLiChun())
def getYearInGanZhiExact(self):
return "%s%s" % (self.getYearGanExact(), self.getYearZhiExact())
def getMonthGan(self):
return LunarUtil.GAN[self.__monthGanIndex + 1]
def getMonthGanExact(self):
return LunarUtil.GAN[self.__monthGanIndexExact + 1]
def getMonthZhi(self):
return LunarUtil.ZHI[self.__monthZhiIndex + 1]
def getMonthZhiExact(self):
return LunarUtil.ZHI[self.__monthZhiIndexExact + 1]
def getMonthInGanZhi(self):
return "%s%s" % (self.getMonthGan(), self.getMonthZhi())
def getMonthInGanZhiExact(self):
return "%s%s" % (self.getMonthGanExact(), self.getMonthZhiExact())
def getDayGan(self):
return LunarUtil.GAN[self.__dayGanIndex + 1]
def getDayGanExact(self):
return LunarUtil.GAN[self.__dayGanIndexExact + 1]
def getDayGanExact2(self):
return LunarUtil.GAN[self.__dayGanIndexExact2 + 1]
def getDayZhi(self):
return LunarUtil.ZHI[self.__dayZhiIndex + 1]
def getDayZhiExact(self):
return LunarUtil.ZHI[self.__dayZhiIndexExact + 1]
def getDayZhiExact2(self):
return LunarUtil.ZHI[self.__dayZhiIndexExact2 + 1]
def getDayInGanZhi(self):
return "%s%s" % (self.getDayGan(), self.getDayZhi())
def getDayInGanZhiExact(self):
return "%s%s" % (self.getDayGanExact(), self.getDayZhiExact())
def getDayInGanZhiExact2(self):
return "%s%s" % (self.getDayGanExact2(), self.getDayZhiExact2())
def getTimeGan(self):
return LunarUtil.GAN[self.__timeGanIndex + 1]
def getTimeZhi(self):
return LunarUtil.ZHI[self.__timeZhiIndex + 1]
def getTimeInGanZhi(self):
return "%s%s" % (self.getTimeGan(), self.getTimeZhi())
def getYearShengXiao(self):
return LunarUtil.SHENGXIAO[self.__yearZhiIndex + 1]
def getYearShengXiaoByLiChun(self):
return LunarUtil.SHENGXIAO[self.__yearZhiIndexByLiChun + 1]
def getYearShengXiaoExact(self):
return LunarUtil.SHENGXIAO[self.__yearZhiIndexExact + 1]
def getMonthShengXiao(self):
return LunarUtil.SHENGXIAO[self.__monthZhiIndex + 1]
def getMonthShengXiaoExact(self):
return LunarUtil.SHENGXIAO[self.__monthZhiIndexExact + 1]
def getDayShengXiao(self):
return LunarUtil.SHENGXIAO[self.__dayZhiIndex + 1]
def getTimeShengXiao(self):
return LunarUtil.SHENGXIAO[self.__timeZhiIndex + 1]
def getYearInChinese(self):
y = str(self.__year)
s = ""
for i in range(0, len(y)):
s += LunarUtil.NUMBER[ord(y[i]) - 48]
return s
def getMonthInChinese(self):
month = self.__month
return ("闰" if month < 0 else "") + LunarUtil.MONTH[abs(month)]
def getDayInChinese(self):
return LunarUtil.DAY[self.__day]
def getPengZuGan(self):
return LunarUtil.PENG_ZU_GAN[self.__dayGanIndex + 1]
def getPengZuZhi(self):
return LunarUtil.PENG_ZU_ZHI[self.__dayZhiIndex + 1]
def getPositionXi(self):
return self.getDayPositionXi()
def getPositionXiDesc(self):
return self.getDayPositionXiDesc()
def getPositionYangGui(self):
return self.getDayPositionYangGui()
def getPositionYangGuiDesc(self):
return self.getDayPositionYangGuiDesc()
def getPositionYinGui(self):
return self.getDayPositionYinGui()
def getPositionYinGuiDesc(self):
return self.getDayPositionYinGuiDesc()
def getPositionFu(self):
return self.getDayPositionFu()
def getPositionFuDesc(self):
return self.getDayPositionFuDesc()
def getPositionCai(self):
return self.getDayPositionCai()
def getPositionCaiDesc(self):
return self.getDayPositionCaiDesc()
def getDayPositionXi(self):
return LunarUtil.POSITION_XI[self.__dayGanIndex + 1]
def getDayPositionXiDesc(self):
return LunarUtil.POSITION_DESC[self.getDayPositionXi()]
def getDayPositionYangGui(self):
return LunarUtil.POSITION_YANG_GUI[self.__dayGanIndex + 1]
def getDayPositionYangGuiDesc(self):
return LunarUtil.POSITION_DESC[self.getDayPositionYangGui()]
def getDayPositionYinGui(self):
return LunarUtil.POSITION_YIN_GUI[self.__dayGanIndex + 1]
def getDayPositionYinGuiDesc(self):
return LunarUtil.POSITION_DESC[self.getDayPositionYinGui()]
def getDayPositionFu(self, sect=2):
return (LunarUtil.POSITION_FU if 1 == sect else LunarUtil.POSITION_FU_2)[self.__dayGanIndex + 1]
def getDayPositionFuDesc(self, sect=2):
return LunarUtil.POSITION_DESC[self.getDayPositionFu(sect)]
def getDayPositionCai(self):
return LunarUtil.POSITION_CAI[self.__dayGanIndex + 1]
def getDayPositionCaiDesc(self):
return LunarUtil.POSITION_DESC[self.getDayPositionCai()]
def getYearPositionTaiSui(self, sect=2):
if 1 == sect:
year_zhi_index = self.__yearZhiIndex
elif 3 == sect:
year_zhi_index = self.__yearZhiIndexExact
else:
year_zhi_index = self.__yearZhiIndexByLiChun
return LunarUtil.POSITION_TAI_SUI_YEAR[year_zhi_index]
def getYearPositionTaiSuiDesc(self, sect=2):
return LunarUtil.POSITION_DESC[self.getYearPositionTaiSui(sect)]
def __getMonthPositionTaiSui(self, month_zhi_index, month_gan_index):
m = month_zhi_index - LunarUtil.BASE_MONTH_ZHI_INDEX
if m < 0:
m += 12
m = m % 4
if 0 == m:
p = "艮"
elif 2 == m:
p = "坤"
elif 3 == m:
p = "巽"
else:
p = LunarUtil.POSITION_GAN[month_gan_index]
return p
def getMonthPositionTaiSui(self, sect=2):
if 3 == sect:
month_zhi_index = self.__monthZhiIndexExact
month_gan_index = self.__monthGanIndexExact
else:
month_zhi_index = self.__monthZhiIndex
month_gan_index = self.__monthGanIndex
return self.__getMonthPositionTaiSui(month_zhi_index, month_gan_index)
def getMonthPositionTaiSuiDesc(self, sect=2):
return LunarUtil.POSITION_DESC[self.getMonthPositionTaiSui(sect)]
def __getDayPositionTaiSui(self, day_in_gan_zhi, year_zhi_index):
if day_in_gan_zhi in "甲子,乙丑,丙寅,丁卯,戊辰,己巳":
p = "震"
elif day_in_gan_zhi in "丙子,丁丑,戊寅,己卯,庚辰,辛巳":
p = "离"
elif day_in_gan_zhi in "戊子,己丑,庚寅,辛卯,壬辰,癸巳":
p = "中"
elif day_in_gan_zhi in "庚子,辛丑,壬寅,癸卯,甲辰,乙巳":
p = "兑"
elif day_in_gan_zhi in "壬子,癸丑,甲寅,乙卯,丙辰,丁巳":
p = "坎"
else:
p = LunarUtil.POSITION_TAI_SUI_YEAR[year_zhi_index]
return p
def getDayPositionTaiSui(self, sect=2):
if 1 == sect:
day_in_gan_zhi = self.getDayInGanZhi()
year_zhi_index = self.__yearZhiIndex
elif 3 == sect:
day_in_gan_zhi = self.getDayInGanZhi()
year_zhi_index = self.__yearZhiIndexExact
else:
day_in_gan_zhi = self.getDayInGanZhiExact2()
year_zhi_index = self.__yearZhiIndexByLiChun
return self.__getDayPositionTaiSui(day_in_gan_zhi, year_zhi_index)
def getDayPositionTaiSuiDesc(self, sect=2):
return LunarUtil.POSITION_DESC[self.getDayPositionTaiSui(sect)]
def getTimePositionXi(self):
return LunarUtil.POSITION_XI[self.__timeGanIndex + 1]
def getTimePositionXiDesc(self):
return LunarUtil.POSITION_DESC[self.getTimePositionXi()]
def getTimePositionYangGui(self):
return LunarUtil.POSITION_YANG_GUI[self.__timeGanIndex + 1]
def getTimePositionYangGuiDesc(self):
return LunarUtil.POSITION_DESC[self.getTimePositionYangGui()]
def getTimePositionYinGui(self):
return LunarUtil.POSITION_YIN_GUI[self.__timeGanIndex + 1]
def getTimePositionYinGuiDesc(self):
return LunarUtil.POSITION_DESC[self.getTimePositionYinGui()]
def getTimePositionFu(self, sect=2):
return (LunarUtil.POSITION_FU if 1 == sect else LunarUtil.POSITION_FU_2)[self.__timeGanIndex + 1]
def getTimePositionFuDesc(self, sect=2):
return LunarUtil.POSITION_DESC[self.getTimePositionFu(sect)]
def getTimePositionCai(self):
return LunarUtil.POSITION_CAI[self.__timeGanIndex + 1]
def getTimePositionCaiDesc(self):
return LunarUtil.POSITION_DESC[self.getTimePositionCai()]
def getChong(self):
return self.getDayChong()
def getDayChong(self):
return LunarUtil.CHONG[self.__dayZhiIndex]
def getTimeChong(self):
return LunarUtil.CHONG[self.__timeZhiIndex]
def getChongGan(self):
return self.getDayChongGan()
def getDayChongGan(self):
return LunarUtil.CHONG_GAN[self.__dayGanIndex]
def getTimeChongGan(self):
return LunarUtil.CHONG_GAN[self.__timeGanIndex]
def getChongGanTie(self):
return self.getDayChongGanTie()
def getDayChongGanTie(self):
return LunarUtil.CHONG_GAN_TIE[self.__dayGanIndex]
def getTimeChongGanTie(self):
return LunarUtil.CHONG_GAN_TIE[self.__timeGanIndex]
def getChongShengXiao(self):
return self.getDayChongShengXiao()
def getDayChongShengXiao(self):
chong = self.getDayChong()
for i in range(0, len(LunarUtil.ZHI)):
if LunarUtil.ZHI[i] == chong:
return LunarUtil.SHENGXIAO[i]
return ""
def getTimeChongShengXiao(self):
chong = self.getTimeChong()
for i in range(0, len(LunarUtil.ZHI)):
if LunarUtil.ZHI[i] == chong:
return LunarUtil.SHENGXIAO[i]
return ""
def getChongDesc(self):
return self.getDayChongDesc()
def getDayChongDesc(self):
return "(" + self.getDayChongGan() + self.getDayChong() + ")" + self.getDayChongShengXiao()
def getTimeChongDesc(self):
return "(" + self.getTimeChongGan() + self.getTimeChong() + ")" + self.getTimeChongShengXiao()
def getSha(self):
return self.getDaySha()
def getDaySha(self):
return LunarUtil.SHA[self.getDayZhi()]
def getTimeSha(self):
return LunarUtil.SHA[self.getTimeZhi()]
def getYearNaYin(self):
return LunarUtil.NAYIN[self.getYearInGanZhi()]
def getMonthNaYin(self):
return LunarUtil.NAYIN[self.getMonthInGanZhi()]
def getDayNaYin(self):
return LunarUtil.NAYIN[self.getDayInGanZhi()]
def getTimeNaYin(self):
return LunarUtil.NAYIN[self.getTimeInGanZhi()]
def getSeason(self):
return LunarUtil.SEASON[abs(self.__month)]
@staticmethod
def __convertJieQi(name):
jq = name
if "DONG_ZHI" == jq:
jq = "冬至"
elif "DA_HAN" == jq:
jq = "大寒"
elif "XIAO_HAN" == jq:
jq = "小寒"
elif "LI_CHUN" == jq:
jq = "立春"
elif "DA_XUE" == jq:
jq = "大雪"
elif "YU_SHUI" == jq:
jq = "雨水"
elif "JING_ZHE" == jq:
jq = "惊蛰"
return jq
def getJie(self):
for i in range(0, len(Lunar.JIE_QI_IN_USE), 2):
key = Lunar.JIE_QI_IN_USE[i]
d = self.__jieQi[key]
if d.getYear() == self.__solar.getYear() and d.getMonth() == self.__solar.getMonth() and d.getDay() == self.__solar.getDay():
return self.__convertJieQi(key)
return ""
def getQi(self):
for i in range(1, len(Lunar.JIE_QI_IN_USE), 2):
key = Lunar.JIE_QI_IN_USE[i]
d = self.__jieQi[key]
if d.getYear() == self.__solar.getYear() and d.getMonth() == self.__solar.getMonth() and d.getDay() == self.__solar.getDay():
return self.__convertJieQi(key)
return ""
def getWeek(self):
return self.__weekIndex
def getWeekInChinese(self):
return SolarUtil.WEEK[self.getWeek()]
def getXiu(self):
return LunarUtil.XIU[self.getDayZhi() + str(self.getWeek())]
def getXiuLuck(self):
return LunarUtil.XIU_LUCK[self.getXiu()]
def getXiuSong(self):
return LunarUtil.XIU_SONG[self.getXiu()]
def getZheng(self):
return LunarUtil.ZHENG[self.getXiu()]
def getAnimal(self):
return LunarUtil.ANIMAL[self.getXiu()]
def getGong(self):
return LunarUtil.GONG[self.getXiu()]
def getShou(self):
return LunarUtil.SHOU[self.getGong()]
def getFestivals(self):
fs = []
md = "%d-%d" % (self.__month, self.__day)
if md in LunarUtil.FESTIVAL:
fs.append(LunarUtil.FESTIVAL[md])
if abs(self.__month) == 12 and self.__day >= 29 and self.__year != self.next(1).getYear():
fs.append("除夕")
return fs
def getOtherFestivals(self):
arr = []
md = "%d-%d" % (self.__month, self.__day)
if md in LunarUtil.OTHER_FESTIVAL:
fs = LunarUtil.OTHER_FESTIVAL[md]
for f in fs:
arr.append(f)
solar_ymd = self.__solar.toYmd()
if solar_ymd == self.__jieQi["清明"].next(-1).toYmd():
arr.append("寒食节")
jq = self.__jieQi["立春"]
offset = 4 - jq.getLunar().getDayGanIndex()
if offset < 0:
offset += 10
if solar_ymd == jq.next(offset + 40).toYmd():
arr.append("春社")
jq = self.__jieQi["立秋"]
offset = 4 - jq.getLunar().getDayGanIndex()
if offset < 0:
offset += 10
if solar_ymd == jq.next(offset + 40).toYmd():
arr.append("秋社")
return arr
def getEightChar(self):
if self.__eightChar is None:
self.__eightChar = EightChar.fromLunar(self)
return self.__eightChar
def getBaZi(self):
ba_zi = self.getEightChar()
return [ba_zi.getYear(), ba_zi.getMonth(), ba_zi.getDay(), ba_zi.getTime()]
def getBaZiWuXing(self):
ba_zi = self.getEightChar()
return [ba_zi.getYearWuXing(), ba_zi.getMonthWuXing(), ba_zi.getDayWuXing(), ba_zi.getTimeWuXing()]
def getBaZiNaYin(self):
ba_zi = self.getEightChar()
return [ba_zi.getYearNaYin(), ba_zi.getMonthNaYin(), ba_zi.getDayNaYin(), ba_zi.getTimeNaYin()]
def getBaZiShiShenGan(self):
ba_zi = self.getEightChar()
return [ba_zi.getYearShiShenGan(), ba_zi.getMonthShiShenGan(), ba_zi.getDayShiShenGan(), ba_zi.getTimeShiShenGan()]
def getBaZiShiShenZhi(self):
ba_zi = self.getEightChar()
return [ba_zi.getYearShiShenZhi()[0], ba_zi.getMonthShiShenZhi()[0], ba_zi.getDayShiShenZhi()[0], ba_zi.getTimeShiShenZhi()[0]]
def getBaZiShiShenYearZhi(self):
return self.getEightChar().getYearShiShenZhi()
def getBaZiShiShenMonthZhi(self):
return self.getEightChar().getMonthShiShenZhi()
def getBaZiShiShenDayZhi(self):
return self.getEightChar().getDayShiShenZhi()
def getBaZiShiShenTimeZhi(self):
return self.getEightChar().getTimeShiShenZhi()
def getZhiXing(self):
offset = self.__dayZhiIndex - self.__monthZhiIndex
if offset < 0:
offset += 12
return LunarUtil.ZHI_XING[offset + 1]
def getDayTianShen(self):
return LunarUtil.TIAN_SHEN[(self.__dayZhiIndex + LunarUtil.ZHI_TIAN_SHEN_OFFSET[self.getMonthZhi()]) % 12 + 1]
def getTimeTianShen(self):
return LunarUtil.TIAN_SHEN[(self.__timeZhiIndex + LunarUtil.ZHI_TIAN_SHEN_OFFSET[self.getDayZhiExact()]) % 12 + 1]
def getDayTianShenType(self):
return LunarUtil.TIAN_SHEN_TYPE[self.getDayTianShen()]
def getTimeTianShenType(self):
return LunarUtil.TIAN_SHEN_TYPE[self.getTimeTianShen()]
def getDayTianShenLuck(self):
return LunarUtil.TIAN_SHEN_TYPE_LUCK[self.getDayTianShenType()]
def getTimeTianShenLuck(self):
return LunarUtil.TIAN_SHEN_TYPE_LUCK[self.getTimeTianShenType()]
def getDayPositionTai(self):
return LunarUtil.POSITION_TAI_DAY[LunarUtil.getJiaZiIndex(self.getDayInGanZhi())]
def getMonthPositionTai(self):
m = self.__month
if m < 0:
return ""
return LunarUtil.POSITION_TAI_MONTH[m - 1]
def getDayYi(self, sect=1):
"""
获取每日宜
:return: 宜
"""
if 2 == sect:
month_gan_zhi = self.getMonthInGanZhiExact()
else:
month_gan_zhi = self.getMonthInGanZhi()
return LunarUtil.getDayYi(month_gan_zhi, self.getDayInGanZhi())
def getDayJi(self, sect=1):
"""
获取每日忌
:return: 忌
"""
if 2 == sect:
month_gan_zhi = self.getMonthInGanZhiExact()
else:
month_gan_zhi = self.getMonthInGanZhi()
return LunarUtil.getDayJi(month_gan_zhi, self.getDayInGanZhi())
def getTimeYi(self):
"""
获取时宜
:return: 宜
"""
return LunarUtil.getTimeYi(self.getDayInGanZhiExact(), self.getTimeInGanZhi())
def getTimeJi(self):
"""
获取时忌
:return: 忌
"""
return LunarUtil.getTimeJi(self.getDayInGanZhiExact(), self.getTimeInGanZhi())
def getDayJiShen(self):
"""
获取日吉神(宜趋)
:return: 日吉神
"""
return LunarUtil.getDayJiShen(self.getMonthZhiIndex(), self.getDayInGanZhi())
def getDayXiongSha(self):
"""
获取日凶煞(宜忌)
:return: 日凶煞
"""
return LunarUtil.getDayXiongSha(self.getMonthZhiIndex(), self.getDayInGanZhi())
def getYueXiang(self):
"""
获取月相
:return: 月相
"""
return LunarUtil.YUE_XIANG[self.__day]
def __getYearNineStar(self, year_in_gan_zhi):
index_exact = LunarUtil.getJiaZiIndex(year_in_gan_zhi) + 1
index = LunarUtil.getJiaZiIndex(self.getYearInGanZhi()) + 1
year_offset = index_exact - index
if year_offset > 1:
year_offset -= 60
elif year_offset < -1:
year_offset += 60
yuan = int((self.__year + year_offset + 2696) / 60) % 3
offset = (62 + yuan * 3 - index_exact) % 9
if 0 == offset:
offset = 9
return NineStar.fromIndex(offset - 1)
def getYearNineStar(self, sect=2):
if 1 == sect:
year_in_gan_zhi = self.getYearInGanZhi()
elif 3 == sect:
year_in_gan_zhi = self.getYearInGanZhiExact()
else:
year_in_gan_zhi = self.getYearInGanZhiByLiChun()
return self.__getYearNineStar(year_in_gan_zhi)
@staticmethod
def __getMonthNineStar(year_zhi_index, month_zhi_index):
index = year_zhi_index % 3
n = 27 - index * 3
if month_zhi_index < LunarUtil.BASE_MONTH_ZHI_INDEX:
n -= 3
offset = (n - month_zhi_index) % 9
return NineStar.fromIndex(offset)
def getMonthNineStar(self, sect=2):
if 1 == sect:
year_zhi_index = self.__yearZhiIndex
month_zhi_index = self.__monthZhiIndex
elif 3 == sect:
year_zhi_index = self.__yearZhiIndexExact
month_zhi_index = self.__monthZhiIndexExact
else:
year_zhi_index = self.__yearZhiIndexByLiChun
month_zhi_index = self.__monthZhiIndex
return self.__getMonthNineStar(year_zhi_index, month_zhi_index)
def getDayNineStar(self):
solar_ymd = self.__solar.toYmd()
dong_zhi = self.__jieQi["冬至"]
dong_zhi2 = self.__jieQi["DONG_ZHI"]
xia_zhi = self.__jieQi["夏至"]
dong_zhi_index = LunarUtil.getJiaZiIndex(dong_zhi.getLunar().getDayInGanZhi())
dong_zhi_index2 = LunarUtil.getJiaZiIndex(dong_zhi2.getLunar().getDayInGanZhi())
xia_zhi_index = LunarUtil.getJiaZiIndex(xia_zhi.getLunar().getDayInGanZhi())
if dong_zhi_index > 29:
solar_shun_bai = dong_zhi.next(60 - dong_zhi_index)
else:
solar_shun_bai = dong_zhi.next(-dong_zhi_index)
solar_shun_bai_ymd = solar_shun_bai.toYmd()
if dong_zhi_index2 > 29:
solar_shun_bai2 = dong_zhi2.next(60 - dong_zhi_index2)
else:
solar_shun_bai2 = dong_zhi2.next(-dong_zhi_index2)
solar_shun_bai_ymd2 = solar_shun_bai2.toYmd()
if xia_zhi_index > 29:
solar_ni_zi = xia_zhi.next(60 - xia_zhi_index)
else:
solar_ni_zi = xia_zhi.next(-xia_zhi_index)
solar_ni_zi_ymd = solar_ni_zi.toYmd()
offset = 0
if solar_shun_bai_ymd <= solar_ymd < solar_ni_zi_ymd:
offset = self.__solar.subtract(solar_shun_bai) % 9
elif solar_ni_zi_ymd <= solar_ymd < solar_shun_bai_ymd2:
offset = 8 - (self.__solar.subtract(solar_ni_zi) % 9)
elif solar_ymd >= solar_shun_bai_ymd2:
offset = self.__solar.subtract(solar_shun_bai2) % 9
elif solar_ymd < solar_shun_bai_ymd:
offset = (8 + solar_shun_bai.subtract(self.__solar)) % 9
return NineStar.fromIndex(offset)
def getTimeNineStar(self):
solar_ymd = self.__solar.toYmd()
asc = False
if self.__jieQi["冬至"].toYmd() <= solar_ymd < self.__jieQi["夏至"].toYmd():
asc = True
elif solar_ymd >= self.__jieQi["DONG_ZHI"].toYmd():
asc = True
start = 6 if asc else 2
day_zhi = self.getDayZhi()
if day_zhi in "子午卯酉":
start = 0 if asc else 8
elif day_zhi in "辰戌丑未":
start = 3 if asc else 5
index = start + self.__timeZhiIndex if asc else start + 9 - self.__timeZhiIndex
return NineStar.fromIndex(index % 9)
def getJieQiTable(self):
return self.__jieQi
def getJieQiList(self):
return self.__jieQiList
def getTimeGanIndex(self):
return self.__timeGanIndex
def getTimeZhiIndex(self):
return self.__timeZhiIndex
def getDayGanIndex(self):
return self.__dayGanIndex
def getDayZhiIndex(self):
return self.__dayZhiIndex
def getDayGanIndexExact(self):
return self.__dayGanIndexExact
def getDayGanIndexExact2(self):
return self.__dayGanIndexExact2
def getDayZhiIndexExact(self):
return self.__dayZhiIndexExact
def getDayZhiIndexExact2(self):
return self.__dayZhiIndexExact2
def getMonthGanIndex(self):
return self.__monthGanIndex
def getMonthZhiIndex(self):
return self.__monthZhiIndex
def getMonthGanIndexExact(self):
return self.__monthGanIndexExact
def getMonthZhiIndexExact(self):
return self.__monthZhiIndexExact
def getYearGanIndex(self):
return self.__yearGanIndex
def getYearZhiIndex(self):
return self.__yearZhiIndex
def getYearGanIndexByLiChun(self):
return self.__yearGanIndexByLiChun
def getYearZhiIndexByLiChun(self):
return self.__yearZhiIndexByLiChun
def getYearGanIndexExact(self):
return self.__yearGanIndexExact
def getYearZhiIndexExact(self):
return self.__yearZhiIndexExact
def getNextJie(self, whole_day=False):
"""
获取下一节(顺推的第一个节)
:param whole_day: 是否按天计
:return: 节气
"""
conditions = []
for i in range(0, int(len(Lunar.JIE_QI_IN_USE) / 2)):
conditions.append(Lunar.JIE_QI_IN_USE[i * 2])
return self.__getNearJieQi(True, conditions, whole_day)
def getPrevJie(self, whole_day=False):
"""
获取上一节(逆推的第一个节)
:param whole_day: 是否按天计
:return: 节气
"""
conditions = []
for i in range(0, int(len(Lunar.JIE_QI_IN_USE) / 2)):
conditions.append(Lunar.JIE_QI_IN_USE[i * 2])
return self.__getNearJieQi(False, conditions, whole_day)
def getNextQi(self, whole_day=False):
"""
获取下一气令(顺推的第一个气令)
:param whole_day: 是否按天计
:return: 节气
"""
conditions = []
for i in range(0, int(len(Lunar.JIE_QI_IN_USE) / 2)):
conditions.append(Lunar.JIE_QI_IN_USE[i * 2 + 1])
return self.__getNearJieQi(True, conditions, whole_day)
def getPrevQi(self, whole_day=False):
"""
获取上一气令(逆推的第一个气令)
:param whole_day: 是否按天计
:return: 节气
"""
conditions = []
for i in range(0, int(len(Lunar.JIE_QI_IN_USE) / 2)):
conditions.append(Lunar.JIE_QI_IN_USE[i * 2 + 1])
return self.__getNearJieQi(False, conditions, whole_day)
def getNextJieQi(self, whole_day=False):
"""
获取下一节气(顺推的第一个节气)
:param whole_day: 是否按天计
:return: 节气
"""
return self.__getNearJieQi(True, None, whole_day)
def getPrevJieQi(self, whole_day=False):
"""
获取上一节气(逆推的第一个节气)
:param whole_day: 是否按天计
:return: 节气
"""
return self.__getNearJieQi(False, None, whole_day)
def __getNearJieQi(self, forward, conditions, whole_day):
"""
获取最近的节气,如果未找到匹配的,返回null
:param forward: 是否顺推,true为顺推,false为逆推
:param conditions: 过滤条件,如果设置过滤条件,仅返回匹配该名称的
:param whole_day: 是否按天计
:return: 节气
"""
name = None
near = None
filters = set()
if conditions is not None:
for cond in conditions:
filters.add(cond)
is_filter = len(filters) > 0
today = self.__solar.toYmd() if whole_day else self.__solar.toYmdHms()
for key in self.JIE_QI_IN_USE:
jq = self.__convertJieQi(key)
if is_filter and not filters.__contains__(jq):
continue
solar = self.__jieQi[key]
day = solar.toYmd() if whole_day else solar.toYmdHms()
if forward:
if day <= today:
continue
if near is None:
name = jq
near = solar
else:
near_day = near.toYmd() if whole_day else near.toYmdHms()
if day < near_day:
name = jq
near = solar
else:
if day > today:
continue
if near is None:
name = jq
near = solar
else:
near_day = near.toYmd() if whole_day else near.toYmdHms()
if day > near_day:
name = jq
near = solar
if near is None:
return None
return JieQi(name, near)
def getJieQi(self):
"""
获取节气名称,如果无节气,返回空字符串
:return: 节气名称
"""
for key in self.__jieQi:
d = self.__jieQi[key]
if d.getYear() == self.__solar.getYear() and d.getMonth() == self.__solar.getMonth() and d.getDay() == self.__solar.getDay():
return self.__convertJieQi(key)
return ""
def getCurrentJieQi(self):
"""
获取当天节气对象,如果无节气,返回None
:return: 节气对象
"""
for key in self.__jieQi:
d = self.__jieQi[key]
if d.getYear() == self.__solar.getYear() and d.getMonth() == self.__solar.getMonth() and d.getDay() == self.__solar.getDay():
return JieQi(self.__convertJieQi(key), self.__solar)
return None
def getCurrentJie(self):
"""
获取当天节令对象,如果无节令,返回None
:return: 节气对象
"""
for i in range(0, len(Lunar.JIE_QI_IN_USE), 2):
key = Lunar.JIE_QI_IN_USE[i]
d = self.__jieQi[key]
if d.getYear() == self.__solar.getYear() and d.getMonth() == self.__solar.getMonth() and d.getDay() == self.__solar.getDay():
return JieQi(self.__convertJieQi(key), d)
return None
def getCurrentQi(self):
"""
获取当天气令对象,如果无气令,返回None
:return: 节气对象
"""
for i in range(1, len(Lunar.JIE_QI_IN_USE), 2):
key = Lunar.JIE_QI_IN_USE[i]
d = self.__jieQi[key]
if d.getYear() == self.__solar.getYear() and d.getMonth() == self.__solar.getMonth() and d.getDay() == self.__solar.getDay():
return JieQi(self.__convertJieQi(key), d)
return None
def next(self, days):
"""
获取往后推几天的农历日期,如果要往前推,则天数用负数
:param days: 天数
:return: 农历日期
"""
return self.__solar.next(days).getLunar()
def __str__(self):
return self.toString()
def toString(self):
return "%s年%s月%s" % (self.getYearInChinese(), self.getMonthInChinese(), self.getDayInChinese())
def toFullString(self):
s = self.toString()
s += " " + self.getYearInGanZhi() + "(" + self.getYearShengXiao() + ")年"
s += " " + self.getMonthInGanZhi() + "(" + self.getMonthShengXiao() + ")月"
s += " " + self.getDayInGanZhi() + "(" + self.getDayShengXiao() + ")日"
s += " " + self.getTimeZhi() + "(" + self.getTimeShengXiao() + ")时"
s += " 纳音[" + self.getYearNaYin() + " " + self.getMonthNaYin() + " " + self.getDayNaYin() + " " + self.getTimeNaYin() + "]"
s += " 星期" + self.getWeekInChinese()
for f in self.getFestivals():
s += " (" + f + ")"
for f in self.getOtherFestivals():
s += " (" + f + ")"
jq = self.getJieQi()
if len(jq) > 0:
s += " [" + jq + "]"
s += " " + self.getGong() + "方" + self.getShou()
s += " 星宿[" + self.getXiu() + self.getZheng() + self.getAnimal() + "](" + self.getXiuLuck() + ")"
s += " 彭祖百忌[" + self.getPengZuGan() + " " + self.getPengZuZhi() + "]"
s += " 喜神方位[" + self.getDayPositionXi() + "](" + self.getDayPositionXiDesc() + ")"
s += " 阳贵神方位[" + self.getDayPositionYangGui() + "](" + self.getDayPositionYangGuiDesc() + ")"
s += " 阴贵神方位[" + self.getDayPositionYinGui() + "](" + self.getDayPositionYinGuiDesc() + ")"
s += " 福神方位[" + self.getDayPositionFu() + "](" + self.getDayPositionFuDesc() + ")"
s += " 财神方位[" + self.getDayPositionCai() + "](" + self.getDayPositionCaiDesc() + ")"
s += " 冲[" + self.getChongDesc() + "]"
s += " 煞[" + self.getSha() + "]"
return s
def getYearXun(self):
"""
获取年所在旬(以正月初一作为新年的开始)
:return: 旬
"""
return LunarUtil.getXun(self.getYearInGanZhi())
def getYearXunByLiChun(self):
"""
获取年所在旬(以立春当天作为新年的开始)
:return: 旬
"""
return LunarUtil.getXun(self.getYearInGanZhiByLiChun())
def getYearXunExact(self):
"""
获取年所在旬(以立春交接时刻作为新年的开始)
:return: 旬
"""
return LunarUtil.getXun(self.getYearInGanZhiExact())
def getYearXunKong(self):
"""
获取值年空亡(以正月初一作为新年的开始)
:return: 空亡(旬空)
"""
return LunarUtil.getXunKong(self.getYearInGanZhi())
def getYearXunKongByLiChun(self):
"""
获取值年空亡(以立春当天作为新年的开始)
:return: 空亡(旬空)
"""
return LunarUtil.getXunKong(self.getYearInGanZhiByLiChun())
def getYearXunKongExact(self):
"""
获取值年空亡(以立春交接时刻作为新年的开始)
:return: 空亡(旬空)
"""
return LunarUtil.getXunKong(self.getYearInGanZhiExact())
def getMonthXun(self):
"""
获取月所在旬(以节交接当天起算)
:return: 旬
"""
return LunarUtil.getXun(self.getMonthInGanZhi())
def getMonthXunExact(self):
"""
获取月所在旬(以节交接时刻起算)
:return: 旬
"""
return LunarUtil.getXun(self.getMonthInGanZhiExact())
def getMonthXunKong(self):
"""
获取值月空亡(以节交接当天起算)
:return: 空亡(旬空)
"""
return LunarUtil.getXunKong(self.getMonthInGanZhi())
def getMonthXunKongExact(self):
"""
获取值月空亡(以节交接时刻起算)
:return: 空亡(旬空)
"""
return LunarUtil.getXunKong(self.getMonthInGanZhiExact())
def getDayXun(self):
"""
获取日所在旬(以节交接当天起算)
:return: 旬
"""
return LunarUtil.getXun(self.getDayInGanZhi())
def getDayXunExact(self):
"""
获取日所在旬(晚子时日柱算明天)
:return: 旬
"""
return LunarUtil.getXun(self.getDayInGanZhiExact())
def getDayXunExact2(self):
"""
获取日所在旬(晚子时日柱算当天)
:return: 旬
"""
return LunarUtil.getXun(self.getDayInGanZhiExact2())
def getDayXunKong(self):
"""
获取值日空亡
:return: 空亡(旬空)
"""
return LunarUtil.getXunKong(self.getDayInGanZhi())
def getDayXunKongExact(self):
"""
获取值日空亡(晚子时日柱算明天)
:return: 空亡(旬空)
"""
return LunarUtil.getXunKong(self.getDayInGanZhiExact())
def getDayXunKongExact2(self):
"""
获取值日空亡(晚子时日柱算当天)
:return: 空亡(旬空)
"""
return LunarUtil.getXunKong(self.getDayInGanZhiExact2())
def getTimeXun(self):
"""
获取时辰所在旬
:return: 旬
"""
return LunarUtil.getXun(self.getTimeInGanZhi())
def getTimeXunKong(self):
"""
获取值时空亡
:return: 空亡(旬空)
"""
return LunarUtil.getXunKong(self.getTimeInGanZhi())
def getShuJiu(self):
"""
获取数九
:return: 数九,如果不是数九天,返回None
"""
current = Solar.fromYmd(self.__solar.getYear(), self.__solar.getMonth(), self.__solar.getDay())
start = self.__jieQi["DONG_ZHI"]
start = Solar.fromYmd(start.getYear(), start.getMonth(), start.getDay())
if current.isBefore(start):
start = self.__jieQi["冬至"]
start = Solar.fromYmd(start.getYear(), start.getMonth(), start.getDay())
end = Solar.fromYmd(start.getYear(), start.getMonth(), start.getDay()).next(81)
if current.isBefore(start) or not current.isBefore(end):
return None
days = current.subtract(start)
return ShuJiu(LunarUtil.NUMBER[int(days / 9) + 1] + "九", days % 9 + 1)
def getFu(self):
"""
获取三伏
:return: 三伏,如果不是伏天,返回None
"""
current = Solar.fromYmd(self.__solar.getYear(), self.__solar.getMonth(), self.__solar.getDay())
xia_zhi = self.__jieQi["夏至"]
li_qiu = self.__jieQi["立秋"]
start = Solar.fromYmd(xia_zhi.getYear(), xia_zhi.getMonth(), xia_zhi.getDay())
add = 6 - xia_zhi.getLunar().getDayGanIndex()
if add < 0:
add += 10
add += 20
start = start.next(add)
if current.isBefore(start):
return None
days = current.subtract(start)
if days < 10:
return Fu("初伏", days + 1)
start = start.next(10)
days = current.subtract(start)
if days < 10:
return Fu("中伏", days + 1)
start = start.next(10)
days = current.subtract(start)
li_qiu_solar = Solar.fromYmd(li_qiu.getYear(), li_qiu.getMonth(), li_qiu.getDay())
if li_qiu_solar.isAfter(start):
if days < 10:
return Fu("中伏", days + 11)
start = start.next(10)
days = current.subtract(start)
if days < 10:
return Fu("末伏", days + 1)
return None
def getLiuYao(self):
"""
获取六曜
:return: 六曜
"""
return LunarUtil.LIU_YAO[(abs(self.__month) + self.__day - 2) % 6]
def getWuHou(self):
"""
获取物候
:return: 物候
"""
jie_qi = self.getPrevJieQi(True)
offset = 0
for i in range(0, len(Lunar.JIE_QI)):
if jie_qi.getName() == Lunar.JIE_QI[i]:
offset = i
break
index = int(self.__solar.subtract(jie_qi.getSolar()) / 5)
if index > 2:
index = 2
return LunarUtil.WU_HOU[(offset * 3 + index) % len(LunarUtil.WU_HOU)]
def getHou(self):
jie_qi = self.getPrevJieQi(True)
size = len(LunarUtil.HOU) - 1
offset = int(self.__solar.subtract(jie_qi.getSolar()) / 5)
if offset > size:
offset = size
return "%s %s" % (jie_qi.getName(), LunarUtil.HOU[offset])
def getDayLu(self):
"""
获取日禄
:return: 日禄
"""
gan = LunarUtil.LU[self.getDayGan()]
zhi = None
if self.getDayZhi() in LunarUtil.LU:
zhi = LunarUtil.LU[self.getDayZhi()]
lu = gan + "命互禄"
if zhi is not None:
lu += " " + zhi + "命进禄"
return lu
def getTime(self):
"""
获取时辰
:return: 时辰
"""
return LunarTime.fromYmdHms(self.__year, self.__month, self.__day, self.__hour, self.__minute, self.__second)
def getTimes(self):
"""
获取当天的时辰列表
:return: 时辰列表
"""
times = [LunarTime.fromYmdHms(self.__year, self.__month, self.__day, 0, 0, 0)]
for i in range(0, 12):
times.append(LunarTime.fromYmdHms(self.__year, self.__month, self.__day, (i+1) * 2-1, 0, 0))
return times
def getFoto(self):
"""
获取佛历
:return: 佛历
"""
from . import Foto
return Foto.fromLunar(self)
def getTao(self):
"""
获取道历
:return: 道历
"""
from . import Tao
return Tao.fromLunar(self)