西暦に基づいて旧暦を計算する。
41256 ワード
#! /usr/bin/env python3
# -*- coding:utf-8 -*-
# Author : mayi
# Blog : http://www.cnblogs.com/mayi0312/
# Date : 2019/1/14
# Name : test01
# Software : PyCharm
# Note :
#
python qun,688244617
、 。
python python, 。
import datetime
# g_lunar_month_day 1901 2050 ,
# 29 30 , 12( 13) , 1 30 , 29
g_lunar_month_day = [
0x4ae0, 0xa570, 0x5268, 0xd260, 0xd950, 0x6aa8, 0x56a0, 0x9ad0, 0x4ae8, 0x4ae0, # 1910
0xa4d8, 0xa4d0, 0xd250, 0xd548, 0xb550, 0x56a0, 0x96d0, 0x95b0, 0x49b8, 0x49b0, # 1920
0xa4b0, 0xb258, 0x6a50, 0x6d40, 0xada8, 0x2b60, 0x9570, 0x4978, 0x4970, 0x64b0, # 1930
0xd4a0, 0xea50, 0x6d48, 0x5ad0, 0x2b60, 0x9370, 0x92e0, 0xc968, 0xc950, 0xd4a0, # 1940
0xda50, 0xb550, 0x56a0, 0xaad8, 0x25d0, 0x92d0, 0xc958, 0xa950, 0xb4a8, 0x6ca0, # 1950
0xb550, 0x55a8, 0x4da0, 0xa5b0, 0x52b8, 0x52b0, 0xa950, 0xe950, 0x6aa0, 0xad50, # 1960
0xab50, 0x4b60, 0xa570, 0xa570, 0x5260, 0xe930, 0xd950, 0x5aa8, 0x56a0, 0x96d0, # 1970
0x4ae8, 0x4ad0, 0xa4d0, 0xd268, 0xd250, 0xd528, 0xb540, 0xb6a0, 0x96d0, 0x95b0, # 1980
0x49b0, 0xa4b8, 0xa4b0, 0xb258, 0x6a50, 0x6d40, 0xada0, 0xab60, 0x9370, 0x4978, # 1990
0x4970, 0x64b0, 0x6a50, 0xea50, 0x6b28, 0x5ac0, 0xab60, 0x9368, 0x92e0, 0xc960, # 2000
0xd4a8, 0xd4a0, 0xda50, 0x5aa8, 0x56a0, 0xaad8, 0x25d0, 0x92d0, 0xc958, 0xa950, # 2010
0xb4a0, 0xb550, 0xb550, 0x55a8, 0x4ba0, 0xa5b0, 0x52b8, 0x52b0, 0xa930, 0x74a8, # 2020
0x6aa0, 0xad50, 0x4da8, 0x4b60, 0x9570, 0xa4e0, 0xd260, 0xe930, 0xd530, 0x5aa0, # 2030
0x6b50, 0x96d0, 0x4ae8, 0x4ad0, 0xa4d0, 0xd258, 0xd250, 0xd520, 0xdaa0, 0xb5a0, # 2040
0x56d0, 0x4ad8, 0x49b0, 0xa4b8, 0xa4b0, 0xaa50, 0xb528, 0x6d20, 0xada0, 0x55b0, # 2050
]
# gLanarMonth 1901 2050 , 0,
g_lunar_month = [
0x00, 0x50, 0x04, 0x00, 0x20, # 1910
0x60, 0x05, 0x00, 0x20, 0x70, # 1920
0x05, 0x00, 0x40, 0x02, 0x06, # 1930
0x00, 0x50, 0x03, 0x07, 0x00, # 1940
0x60, 0x04, 0x00, 0x20, 0x70, # 1950
0x05, 0x00, 0x30, 0x80, 0x06, # 1960
0x00, 0x40, 0x03, 0x07, 0x00, # 1970
0x50, 0x04, 0x08, 0x00, 0x60, # 1980
0x04, 0x0a, 0x00, 0x60, 0x05, # 1990
0x00, 0x30, 0x80, 0x05, 0x00, # 2000
0x40, 0x02, 0x07, 0x00, 0x50, # 2010
0x04, 0x09, 0x00, 0x60, 0x04, # 2020
0x00, 0x20, 0x60, 0x05, 0x00, # 2030
0x30, 0xb0, 0x06, 0x00, 0x50, # 2040
0x02, 0x07, 0x00, 0x50, 0x03 # 2050
]
#
ly = ' '
#
lm = ' '
#
ld = ' '
def strToDate(c_date):
"""
8
:param c_date: 8
:return: : -1 , -2 ,
"""
if len(c_date) != 8:
#
return -1
#
year = int(c_date[:4])
#
month = int(c_date[4:6])
#
day = int(c_date[6:])
try:
d_date = datetime.date(int(year), int(month), int(day))
return d_date
except:
# ,
return -2
def lunarYearDays(year):
"""
:param year: ( )
:return:
"""
days = 0
for i in range(1, 13):
(high, low) = lunarMonthDays(year, i)
days += high
days += low
return days
def lunarMonthDays(year, month):
"""
:param year: ( )
:param month: ( )
:return:
"""
if (year < 1901):
return 30
high, low = 0, 29
iBit = 16 - month
if (month > getLeapMonth(year)) and getLeapMonth(year):
iBit -= 1
if (g_lunar_month_day[year - 1901] & (1 << iBit)):
low += 1
if (month == getLeapMonth(year)):
if (g_lunar_month_day[year - 1901] & (1 << (iBit - 1))):
high = 30
else:
high = 29
return (high, low)
def getLeapMonth(year):
"""
, 0,
:param year: ( )
:return: , , 0
"""
flag = g_lunar_month[(year - 1901) // 2]
if (year - 1901) % 2:
return flag & 0x0f
else:
return flag >> 4
def lunarDate(d_date):
"""
( )
:param d_date:
:return:
"""
# 1901.1.1 ,
delta_days = (d_date - datetime.date(1901, 1, 1)).days
# 1901 02 19 1901
# 1901 01 01 1901 02 19 49
if delta_days < 49:
year = 1901 - 1
if delta_days < 19:
month = 11
day = delta_days + 11
else:
month = 12
day = delta_days - 18
else:
# 1901
delta_days -= 49
year, month, day = 1901, 1, 1
#
temp = lunarYearDays(year)
while delta_days >= temp:
delta_days -= temp
year += 1
temp = lunarYearDays(year)
#
(foo, temp) = lunarMonthDays(year, month)
while delta_days >= temp:
delta_days -= temp
if (month == getLeapMonth(year)):
(temp, foo) = lunarMonthDays(year, month)
if (delta_days < temp):
year, month, day = 0, 0, 0
delta_days -= temp
month += 1
(foo, temp) = lunarMonthDays(year, month)
#
day += delta_days
#
temp_year = str(year)
year = ""
for i in temp_year:
year += ly[int(i)]
return " :%s %s %s" % (year, lm[month - 1], ld[(day - 1) * 2:day * 2])
#
def main():
# 8 ( )
c_date = input(" 8 ( :20180101):")
# 8
d_date = strToDate(c_date)
if d_date == -1:
print(" !")
return -1
elif d_date == -2:
print(" !")
return -1
#
l_date = lunarDate(d_date)
# 、
print(" :%s" % (d_date))
print(l_date)
#
if __name__ == '__main__':
main()
実験結果は以下の通りです。 8 ( :20180101):20190114
:2019-01-14
: