mirror of
https://github.com/infinet/lunar-calendar.git
synced 2026-01-12 13:15:28 +08:00
port from Python 2 to Python 3
This commit is contained in:
@@ -22,7 +22,7 @@ calendar, thunderbird + lightning插件, iphone/ipad, 安卓都支持。
|
||||
|
||||
### 系统要求
|
||||
|
||||
* Python: python 2.7上测试可用
|
||||
* Python: python 3.5上测试可用
|
||||
|
||||
* [Numpy][] 和 [Numexpr][]: 纯Python速度较慢,而天文算法特别是完全版的VSOP87和LEA-406计算量尤其大,所以最好配合Numpy以加快计算速度。
|
||||
|
||||
@@ -120,7 +120,7 @@ of using their conversion table, which is only for Non-Commercial use.
|
||||
|
||||
### Requirement:
|
||||
|
||||
* Python: tested on python 2.7
|
||||
* Python: tested on python 3.5
|
||||
|
||||
* [Numpy][] and [Numexpr][]: Only needed when generate calendar by astronomical
|
||||
algorithm. The full version of LEA-406 and VSOP87 is rather slow when compute
|
||||
|
||||
130
aa.py
130
aa.py
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
''' Implement astronomical algorithms for finding solar terms and moon phases.
|
||||
@@ -20,9 +20,11 @@ __license__ = 'BSD'
|
||||
__copyright__ = '2020, Chen Wei <weichen302@gmail.com>'
|
||||
__version__ = '0.0.3'
|
||||
|
||||
from numpy import *
|
||||
import numexpr as ne
|
||||
import math
|
||||
from math import sin,cos,pi
|
||||
import re
|
||||
import numpy as np
|
||||
import numexpr as ne
|
||||
|
||||
J2000 = 2451545.0
|
||||
SYNODIC_MONTH = 29.53
|
||||
@@ -40,7 +42,7 @@ TWOPI = 2 * pi
|
||||
#
|
||||
# Luni-Solar argument multipliers, coefficients, unit 1e-7 arcsec
|
||||
# L L' F D Om longitude (sin, t*sin, cos), obliquity (cos, t*cos, sin)
|
||||
IAU2000BNutationTable = array([
|
||||
IAU2000BNutationTbl = np.array([
|
||||
[ 0, 0, 0, 0, 1, -172064161, -174666, 33386, 92052331, 9086, 15377 ],
|
||||
[ 0, 0, 2, -2, 2, -13170906, -1675, -13696, 5730336, -3015, -4587 ],
|
||||
[ 0, 0, 2, 0, 2, -2276413, -234, 2796, 978459, -485, 1374 ],
|
||||
@@ -121,7 +123,7 @@ IAU2000BNutationTable = array([
|
||||
])
|
||||
|
||||
# Truncated VSOP87D tables
|
||||
earth_L0 = array([
|
||||
earth_L0 = np.array([
|
||||
[ 1.75347045673, 0, 0 ],
|
||||
[ 0.03341656456, 4.66925680417, 6283.0758499914 ],
|
||||
[ 0.00034894275, 4.62610241759, 12566.1516999828 ],
|
||||
@@ -297,7 +299,7 @@ earth_L0 = array([
|
||||
# 172 terms retained
|
||||
])
|
||||
|
||||
earth_L1 = array([
|
||||
earth_L1 = np.array([
|
||||
[ 6283.31966747491, 0, 0 ],
|
||||
[ 0.00206058863, 2.67823455584, 6283.0758499914 ],
|
||||
[ 0.0000430343, 2.63512650414, 12566.1516999828 ],
|
||||
@@ -466,7 +468,7 @@ earth_L1 = array([
|
||||
# 165 terms retained
|
||||
])
|
||||
|
||||
earth_L2 = array([
|
||||
earth_L2 = np.array([
|
||||
[ 0.0005291887, 0, 0 ],
|
||||
[ 0.00008719837, 1.07209665242, 6283.0758499914 ],
|
||||
[ 0.00000309125, 0.86728818832, 12566.1516999828 ],
|
||||
@@ -563,7 +565,7 @@ earth_L2 = array([
|
||||
# 93 terms retained
|
||||
])
|
||||
|
||||
earth_L3 = array([
|
||||
earth_L3 = np.array([
|
||||
[ 0.00000289226, 5.84384198723, 6283.0758499914 ],
|
||||
[ 0.00000034955, 0, 0 ],
|
||||
[ 0.00000016819, 5.48766912348, 12566.1516999828 ],
|
||||
@@ -575,7 +577,7 @@ earth_L3 = array([
|
||||
# 8 terms retained
|
||||
])
|
||||
|
||||
earth_L4 = array([
|
||||
earth_L4 = np.array([
|
||||
[ 0.00000114084, 3.14159265359, 0 ],
|
||||
[ 0.00000007717, 4.13446589358, 6283.0758499914 ],
|
||||
[ 0.00000000765, 3.83803776214, 12566.1516999828 ],
|
||||
@@ -583,7 +585,7 @@ earth_L4 = array([
|
||||
# 4 terms retained
|
||||
])
|
||||
|
||||
earth_L5 = array([
|
||||
earth_L5 = np.array([
|
||||
[ 0.00000000878, 3.14159265359, 0 ],
|
||||
[ 0.00000000172, 2.7657906951, 6283.0758499914 ],
|
||||
[ 0.0000000005, 2.01353298182, 155.4203994342 ],
|
||||
@@ -591,7 +593,7 @@ earth_L5 = array([
|
||||
# 4 terms retained
|
||||
])
|
||||
|
||||
earth_B0 = array([
|
||||
earth_B0 = np.array([
|
||||
[ 0.0000027962, 3.19870156017, 84334.66158130829 ],
|
||||
[ 0.00000101643, 5.42248619256, 5507.5532386674 ],
|
||||
[ 0.00000080445, 3.88013204458, 5223.6939198022 ],
|
||||
@@ -615,7 +617,7 @@ earth_B0 = array([
|
||||
# 20 terms retained
|
||||
])
|
||||
|
||||
earth_B1 = array([
|
||||
earth_B1 = np.array([
|
||||
[ 0.0000000903, 3.8972906189, 5507.5532386674 ],
|
||||
[ 0.00000006177, 1.73038850355, 5223.6939198022 ],
|
||||
[ 0.000000038, 5.24404145734, 2352.8661537718 ],
|
||||
@@ -631,7 +633,7 @@ earth_B1 = array([
|
||||
# 12 terms retained
|
||||
])
|
||||
|
||||
earth_B2 = array([
|
||||
earth_B2 = np.array([
|
||||
[ 0.00000001662, 1.62703209173, 84334.66158130829 ],
|
||||
[ 0.00000000492, 2.41382223971, 1047.7473117547 ],
|
||||
[ 0.00000000344, 2.24353004539, 5507.5532386674 ],
|
||||
@@ -639,17 +641,17 @@ earth_B2 = array([
|
||||
# 4 terms retained
|
||||
])
|
||||
|
||||
earth_B3 = array([
|
||||
earth_B3 = np.array([
|
||||
[ 0, 0, 0 ],
|
||||
# 0 terms retained
|
||||
])
|
||||
|
||||
earth_B4 = array([
|
||||
earth_B4 = np.array([
|
||||
[ 0, 0, 0 ],
|
||||
# 0 terms retained
|
||||
])
|
||||
|
||||
earth_R0 = array([
|
||||
earth_R0 = np.array([
|
||||
[ 1.00013988799, 0, 0 ],
|
||||
[ 0.01670699626, 3.09846350771, 6283.0758499914 ],
|
||||
[ 0.00013956023, 3.0552460962, 12566.1516999828 ],
|
||||
@@ -725,7 +727,7 @@ earth_R0 = array([
|
||||
# 72 terms retained
|
||||
])
|
||||
|
||||
earth_R1 = array([
|
||||
earth_R1 = np.array([
|
||||
[ 0.00103018608, 1.10748969588, 6283.0758499914 ],
|
||||
[ 0.00001721238, 1.06442301418, 12566.1516999828 ],
|
||||
[ 0.00000702215, 3.14159265359, 0 ],
|
||||
@@ -739,7 +741,7 @@ earth_R1 = array([
|
||||
# 10 terms retained
|
||||
])
|
||||
|
||||
earth_R2 = array([
|
||||
earth_R2 = np.array([
|
||||
[ 0.00004359385, 5.78455133738, 6283.0758499914 ],
|
||||
[ 0.00000123633, 5.57934722157, 12566.1516999828 ],
|
||||
[ 0.00000012341, 3.14159265359, 0 ],
|
||||
@@ -749,18 +751,18 @@ earth_R2 = array([
|
||||
# 6 terms retained
|
||||
])
|
||||
|
||||
earth_R3 = array([
|
||||
earth_R3 = np.array([
|
||||
[ 0.00000144595, 4.27319435148, 6283.0758499914 ],
|
||||
[ 0.00000006729, 3.91697608662, 12566.1516999828 ],
|
||||
# 2 terms retained
|
||||
])
|
||||
|
||||
earth_R4 = array([
|
||||
earth_R4 = np.array([
|
||||
[ 0.00000003858, 2.56384387339, 6283.0758499914 ],
|
||||
# 1 terms retained
|
||||
])
|
||||
|
||||
earth_R5 = array([
|
||||
earth_R5 = np.array([
|
||||
[ 0, 0, 0 ],
|
||||
# 0 terms retained
|
||||
])
|
||||
@@ -774,7 +776,7 @@ earth_R5 = array([
|
||||
# terms of 3rd-degree and 4th-degree are ignored
|
||||
# in arcsec
|
||||
# average error Moon = 0.73", max 1.5"
|
||||
M_ARG = array([
|
||||
M_ARG = np.array([
|
||||
# 226 terms
|
||||
[ 485868.249036, 1717915923.21779990, 31.87920 ],
|
||||
[ 1658653.158348, 1488007279.20020032, -44.62040 ],
|
||||
@@ -1009,7 +1011,7 @@ M_ARG = array([
|
||||
# Ak1 mas/yr Amplitude of the 1st-order Poisson term
|
||||
# Ak2 uas/yr2 Amplitude of the 2nd-order Poisson term
|
||||
# [ Ak0, Ak1, Ak2 ] ...
|
||||
M_AMP = array([
|
||||
M_AMP = np.array([
|
||||
# 226 terms
|
||||
[ 22639.5864251, 0.190648, 5.529914 ],
|
||||
[ 4586.4946082, 0.112352, 1.480719 ],
|
||||
@@ -1244,7 +1246,7 @@ M_AMP = array([
|
||||
# phik1 arcsec Phase of the 1st-order Poisson term
|
||||
# phik2 arcsec Phase of the 2nd-order Poisson term
|
||||
# [ phik0, phik1, phik2 ] ...
|
||||
M_PHASE = array([
|
||||
M_PHASE = np.array([
|
||||
# 226 terms
|
||||
[ 0.000383901368, -85.864631587374, -90.051320519700 ],
|
||||
[ 0.002465002781, 43.853451435402, -89.760808801732 ],
|
||||
@@ -1476,16 +1478,16 @@ M_PHASE = array([
|
||||
|
||||
# post process of LEA-406 tables
|
||||
# horizontal split the numpy array
|
||||
F0_V, F1_V, F2_V = hsplit(M_ARG, 3)
|
||||
F0_V, F1_V, F2_V = np.hsplit(M_ARG, 3)
|
||||
CV = M_PHASE * DEG2RAD
|
||||
C_V, CT_V, CTT_V = hsplit(CV, 3)
|
||||
A_V, AT_V, ATT_V = hsplit(M_AMP, 3)
|
||||
C_V, CT_V, CTT_V = np.hsplit(CV, 3)
|
||||
A_V, AT_V, ATT_V = np.hsplit(M_AMP, 3)
|
||||
|
||||
|
||||
def vsopLx(vsopterms, t):
|
||||
''' helper function for calculate VSOP87 '''
|
||||
|
||||
lx = vsopterms[:, 0] * cos(vsopterms[:, 1] + vsopterms[:, 2] * t)
|
||||
lx = vsopterms[:, 0] * np.cos(vsopterms[:, 1] + vsopterms[:, 2] * t)
|
||||
|
||||
return sum(lx)
|
||||
|
||||
@@ -1520,18 +1522,6 @@ def vsop(jde, FK5=True):
|
||||
lon = (L0 + t * (L1 + t * (L2 + t * (L3 + t * (L4 + t * L5)))))
|
||||
|
||||
if FK5:
|
||||
#b0 = vsopLx(earth_B0, t)
|
||||
#b1 = vsopLx(earth_B1, t)
|
||||
#b2 = vsopLx(earth_B2, t)
|
||||
#b3 = vsopLx(earth_B3, t)
|
||||
#b4 = vsopLx(earth_B4, t)
|
||||
#lat = b0 + t * (b1 + t * (b2 + t * (b3 + t * b4 )))
|
||||
#lp = lon - 1.397 * t - 0.00031 * t * t
|
||||
#deltalon = (-0.09033 + 0.03916 * (cos(lp) + sin(lp))
|
||||
# * tan(lat)) * ASEC2RAD
|
||||
#print 'FK5 convertion: %s' % fmtdeg(math.degrees(deltalon))
|
||||
# appears -0.09033 is good enough
|
||||
#deltal = math.radians(-0.09033 / 3600.0)
|
||||
deltalon = -4.379321981462438e-07
|
||||
lon += deltalon
|
||||
|
||||
@@ -1555,7 +1545,7 @@ def rootbysecand(f, angle, x0, x1, precision=0.000000001):
|
||||
|
||||
def normrad(r):
|
||||
''' covernt radian to 0 - 2pi '''
|
||||
alpha = fmod(r, TWOPI)
|
||||
alpha = math.fmod(r, TWOPI)
|
||||
if alpha < 0:
|
||||
alpha += TWOPI
|
||||
return alpha
|
||||
@@ -1563,7 +1553,7 @@ def normrad(r):
|
||||
|
||||
def npitopi(r):
|
||||
''' convert an angle in radians into (-pi, +pi] '''
|
||||
r = fmod(r, TWOPI)
|
||||
r = math.fmod(r, TWOPI)
|
||||
if r > PI:
|
||||
r -= TWOPI
|
||||
elif r <= -1.0 * PI:
|
||||
@@ -1582,7 +1572,7 @@ def fmtdeg(fdegree):
|
||||
sign =''
|
||||
if fdegree < 0:
|
||||
sign = '-'
|
||||
res = '''%s%d%s%d'%.6f"''' % (sign, int(deg), u'\N{DEGREE SIGN}',
|
||||
res = '''%s%d%s%d'%.6f"''' % (sign, int(deg), '\N{DEGREE SIGN}',
|
||||
math.floor(minutes), secs)
|
||||
return res
|
||||
|
||||
@@ -1689,8 +1679,8 @@ def findnewmoons(start, count=15):
|
||||
b = newmoon(start)
|
||||
if b != nm:
|
||||
if nm > 0 and abs(nm - b) > (SYNODIC_MONTH + 1):
|
||||
print 'last newmoon %s, found %s' % (fmtjde2ut(nm),
|
||||
fmtjde2ut(b))
|
||||
print('last newmoon %s, found %s' % (fmtjde2ut(nm),
|
||||
fmtjde2ut(b)))
|
||||
newmoons.append(b)
|
||||
nm = b
|
||||
nmcount += 1
|
||||
@@ -1753,8 +1743,8 @@ def lightabbr_low(jde):
|
||||
# Sun's distance from the Earth, in AU
|
||||
#R = (1.000001018 * (1 - e * e)) / (1 + e * cos(math.radians(v)))
|
||||
# finally, the aberration in radians
|
||||
labbr = (math.radians(20.49552 / 3600.0) * (1 + e * cos(math.radians(v))) /
|
||||
-1.000001018)
|
||||
labbr = (math.radians(20.49552 / 3600.0)
|
||||
* (1 + e * math.cos(math.radians(v))) / -1.000001018)
|
||||
return labbr
|
||||
|
||||
|
||||
@@ -1886,7 +1876,7 @@ def jd2g(jd):
|
||||
|
||||
jd += 0.5
|
||||
z = int(jd)
|
||||
f = fmod(jd, 1.0) # decimal part
|
||||
f = math.fmod(jd, 1.0) # decimal part
|
||||
if z < 2299161:
|
||||
a = z
|
||||
else:
|
||||
@@ -2187,10 +2177,10 @@ def nutation(jde):
|
||||
#Mean longitude of the ascending node of the Moon.
|
||||
Om = 450160.398036 - t * 6962890.5431
|
||||
|
||||
m1, m2, m3, m4, m5, AA, BB, CC, EE, DD, FF = hsplit(IAU2000BNutationTable,
|
||||
m1, m2, m3, m4, m5, AA, BB, CC, EE, DD, FF = np.hsplit(IAU2000BNutationTbl,
|
||||
11)
|
||||
args = (m1 * L + m2 * Lp + m3 * F + m4 * D + m5 * Om) * ASEC2RAD
|
||||
lon = sum((AA + BB * t) * sin(args) + CC * cos(args))
|
||||
lon = sum((AA + BB * t) * np.sin(args) + CC * np.cos(args))
|
||||
|
||||
# unit of longitude is 1.0e-7 arcsec, convert it to arcsec
|
||||
lon *= 1.0e-7
|
||||
@@ -2201,7 +2191,7 @@ def nutation(jde):
|
||||
lon += deplan
|
||||
|
||||
lon *= ASEC2RAD # Convert from arcsec to radians
|
||||
lon = fmod(lon, TWOPI)
|
||||
lon = math.fmod(lon, TWOPI)
|
||||
|
||||
return lon
|
||||
|
||||
@@ -2236,7 +2226,7 @@ def fortran_readline(line, fmt):
|
||||
tmp = []
|
||||
i = 0
|
||||
for rep, ftype, length in fw:
|
||||
for cnt in xrange(rep):
|
||||
for cnt in range(rep):
|
||||
field = line[i: i + length]
|
||||
i += length
|
||||
if ftype == 'F':
|
||||
@@ -2261,7 +2251,7 @@ def fortran_read(fp, fmt):
|
||||
tmp = []
|
||||
i = 0
|
||||
for rep, ftype, length in fw:
|
||||
for cnt in xrange(rep):
|
||||
for cnt in range(rep):
|
||||
field = line[i: i + length]
|
||||
i += length
|
||||
if ftype == 'F':
|
||||
@@ -2391,7 +2381,7 @@ class LEA406():
|
||||
CTT_V.append(a[20])
|
||||
|
||||
# CALCULATING THE ARGUMENTS [RAD]
|
||||
for K in xrange(14):
|
||||
for K in range(14):
|
||||
F0_V[I] += IND[K] * FR[K][0]
|
||||
F1_V[I] += IND[K] * FR[K][1]
|
||||
F2_V[I] += IND[K] * FR[K][2]
|
||||
@@ -2399,19 +2389,19 @@ class LEA406():
|
||||
F4_V[I] += IND[K] * FR[K][4]
|
||||
|
||||
LEN_KEPT = LEN - count
|
||||
print '%d skipped, %d kept' % (count, LEN_KEPT)
|
||||
self.A_V =array(A_V)
|
||||
self.AT_V =array(AT_V)
|
||||
self.ATT_V =array(ATT_V)
|
||||
self.C_V =array(C_V) * DEG2RAD
|
||||
self.CT_V =array(CT_V) * DEG2RAD
|
||||
self.CTT_V =array(CTT_V) * DEG2RAD
|
||||
print('%d skipped, %d kept' % (count, LEN_KEPT))
|
||||
self.A_V =np.array(A_V)
|
||||
self.AT_V =np.array(AT_V)
|
||||
self.ATT_V =np.array(ATT_V)
|
||||
self.C_V =np.array(C_V) * DEG2RAD
|
||||
self.CT_V =np.array(CT_V) * DEG2RAD
|
||||
self.CTT_V =np.array(CTT_V) * DEG2RAD
|
||||
|
||||
self.F0_V = array(F0_V) * 3600
|
||||
self.F1_V = array(F1_V)
|
||||
self.F2_V = array(F2_V)
|
||||
self.F3_V = array(F3_V)
|
||||
self.F4_V = array(F4_V)
|
||||
self.F0_V = np.array(F0_V) * 3600
|
||||
self.F1_V = np.array(F1_V)
|
||||
self.F2_V = np.array(F2_V)
|
||||
self.F3_V = np.array(F3_V)
|
||||
self.F4_V = np.array(F4_V)
|
||||
self.I_V = I
|
||||
|
||||
def lon(self, jd, ignorenutation=False):
|
||||
@@ -2480,11 +2470,11 @@ def main():
|
||||
#jd = 2444239.5
|
||||
jd = g2jd(1900, 1, 1)
|
||||
#lea406class = LEA406()
|
||||
for i in xrange(1):
|
||||
for i in range(1):
|
||||
#l = normrad(lea406class.lon(jd))
|
||||
l = normrad(lea406(jd))
|
||||
#d = fmtdeg(math.degrees(npitopi(e -l )))
|
||||
print jd, l, fmtdeg(math.degrees(l))
|
||||
print((jd, l, fmtdeg(math.degrees(l))))
|
||||
jd += 2000
|
||||
#print fmtdeg(math.degrees(e) % 360.0)
|
||||
#angle = -105
|
||||
@@ -2497,8 +2487,8 @@ def main():
|
||||
def test():
|
||||
jd = 2411545.0
|
||||
year = 2097
|
||||
for year in xrange(2060, 2060):
|
||||
print year, deltaT(year, 9)
|
||||
for year in range(2060, 2060):
|
||||
print(year, deltaT(year, 9))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
19
aa_full.py
19
aa_full.py
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
''' Implement astronomical algorithms for finding solar terms and moon phases.
|
||||
@@ -20,7 +20,10 @@ __license__ = 'BSD'
|
||||
__copyright__ = '2020, Chen Wei <weichen302@gmail.com>'
|
||||
__version__ = '0.0.3'
|
||||
|
||||
from numpy import *
|
||||
import math
|
||||
from math import pi, fmod
|
||||
|
||||
import numpy as np
|
||||
import numexpr as ne
|
||||
from aa import lightabbr_high
|
||||
from aa import nutation
|
||||
@@ -41,7 +44,7 @@ TWOPI = 2 * pi
|
||||
def vsopLx(vsopterms, t):
|
||||
''' helper function for calculate VSOP87 '''
|
||||
|
||||
lx = vsopterms[:, 0] * cos(vsopterms[:, 1] + vsopterms[:, 2] * t)
|
||||
lx = vsopterms[:, 0] * np.cos(vsopterms[:, 1] + vsopterms[:, 2] * t)
|
||||
|
||||
return sum(lx)
|
||||
|
||||
@@ -280,10 +283,10 @@ FRM = [785939.924268, 1732564372.3047, -5.279, .006665, -5.522e-5]
|
||||
from aa_full_table import M_ARG, M_AMP, M_PHASE
|
||||
|
||||
# post import process of LEA-406 tables, horizontal split the numpy array
|
||||
F0_V, F1_V, F2_V, F3_V, F4_V = hsplit(M_ARG, 5)
|
||||
F0_V, F1_V, F2_V, F3_V, F4_V = np.hsplit(M_ARG, 5)
|
||||
CV = M_PHASE * DEG2RAD
|
||||
C_V, CT_V, CTT_V = hsplit(CV, 3)
|
||||
A_V, AT_V, ATT_V = hsplit(M_AMP, 3)
|
||||
C_V, CT_V, CTT_V = np.hsplit(CV, 3)
|
||||
A_V, AT_V, ATT_V = np.hsplit(M_AMP, 3)
|
||||
|
||||
|
||||
def lea406_full(jd, ignorenutation=False):
|
||||
@@ -322,10 +325,10 @@ def lea406_full(jd, ignorenutation=False):
|
||||
def main():
|
||||
#jd = 2444239.5
|
||||
jd = g2jd(1900, 1, 1)
|
||||
for i in xrange(10):
|
||||
for i in range(10):
|
||||
l = normrad(lea406_full(jd))
|
||||
#d = fmtdeg(math.degrees(npitopi(e -l )))
|
||||
print jd, l, fmtdeg(math.degrees(l))
|
||||
print(jd, l, fmtdeg(math.degrees(l)))
|
||||
jd += 2000
|
||||
#print fmtdeg(math.degrees(e) % 360.0)
|
||||
#angle = -105
|
||||
|
||||
166
lunar_ical.py
166
lunar_ical.py
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
'''get lunar calendar from hk observatory
|
||||
@@ -12,23 +12,22 @@ __license__ = 'BSD'
|
||||
__copyright__ = '2020, Chen Wei <weichen302@gmail.com>'
|
||||
__version__ = '0.0.3'
|
||||
|
||||
from StringIO import StringIO
|
||||
from io import StringIO
|
||||
from datetime import datetime
|
||||
from datetime import timedelta
|
||||
import cookielib
|
||||
import getopt
|
||||
import gzip
|
||||
import os
|
||||
import re
|
||||
import sqlite3
|
||||
import sys
|
||||
import urllib2
|
||||
import urllib.request
|
||||
import zlib
|
||||
from lunarcalbase import cn_lunarcal
|
||||
|
||||
APPDIR = os.path.abspath(os.path.dirname(__file__))
|
||||
DB_FILE = os.path.join(APPDIR, 'db', 'lunarcal.sqlite')
|
||||
RE_CAL = re.compile(u'(\d{4})年(\d{1,2})月(\d{1,2})日')
|
||||
RE_CAL = re.compile('(\d{4})年(\d{1,2})月(\d{1,2})日')
|
||||
#PROXY = {'http': 'http://localhost:8001'}
|
||||
PROXY = None
|
||||
URL = 'https://www.hko.gov.hk/tc/gts/time/calendar/text/files/T%dc.txt'
|
||||
@@ -55,31 +54,31 @@ ICAL_SEC = ('BEGIN:VEVENT\n'
|
||||
|
||||
ICAL_END = 'END:VCALENDAR'
|
||||
|
||||
CN_DAY = {u'初二': 2, u'初三': 3, u'初四': 4, u'初五': 5, u'初六': 6,
|
||||
u'初七': 7, u'初八': 8, u'初九': 9, u'初十': 10, u'十一': 11,
|
||||
u'十二': 12, u'十三': 13, u'十四': 14, u'十五': 15, u'十六': 16,
|
||||
u'十七': 17, u'十八': 18, u'十九': 19, u'二十': 20, u'廿一': 21,
|
||||
u'廿二': 22, u'廿三': 23, u'廿四': 24, u'廿五': 25, u'廿六': 26,
|
||||
u'廿七': 27, u'廿八': 28, u'廿九': 29, u'三十': 30}
|
||||
CN_DAY = {'初二': 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}
|
||||
|
||||
CN_MON = {u'正月': 1, u'二月': 2, u'三月': 3, u'四月': 4,
|
||||
u'五月': 5, u'六月': 6, u'七月': 7, u'八月': 8,
|
||||
u'九月': 9, u'十月': 10, u'十一月': 11, u'十二月': 12,
|
||||
CN_MON = {'正月': 1, '二月': 2, '三月': 3, '四月': 4,
|
||||
'五月': 5, '六月': 6, '七月': 7, '八月': 8,
|
||||
'九月': 9, '十月': 10, '十一月': 11, '十二月': 12,
|
||||
|
||||
u'閏正月': 101, u'閏二月': 102, u'閏三月': 103, u'閏四月': 104,
|
||||
u'閏五月': 105, u'閏六月': 106, u'閏七月': 107, u'閏八月': 108,
|
||||
u'閏九月': 109, u'閏十月': 110, u'閏十一月': 111, u'閏十二月': 112}
|
||||
'閏正月': 101, '閏二月': 102, '閏三月': 103, '閏四月': 104,
|
||||
'閏五月': 105, '閏六月': 106, '閏七月': 107, '閏八月': 108,
|
||||
'閏九月': 109, '閏十月': 110, '閏十一月': 111, '閏十二月': 112}
|
||||
|
||||
GAN = (u'庚', u'辛', u'壬', u'癸', u'甲', u'乙', u'丙', u'丁', u'戊', u'己')
|
||||
ZHI = (u'申', u'酉', u'戌', u'亥', u'子', u'丑',
|
||||
u'寅', u'卯', u'辰', u'巳', u'午', u'未')
|
||||
SX = (u'猴', u'鸡', u'狗', u'猪', u'鼠', u'牛',
|
||||
u'虎', u'兔', u'龙', u'蛇', u'马', u'羊')
|
||||
GAN = ('庚', '辛', '壬', '癸', '甲', '乙', '丙', '丁', '戊', '己')
|
||||
ZHI = ('申', '酉', '戌', '亥', '子', '丑',
|
||||
'寅', '卯', '辰', '巳', '午', '未')
|
||||
SX = ('猴', '鸡', '狗', '猪', '鼠', '牛',
|
||||
'虎', '兔', '龙', '蛇', '马', '羊')
|
||||
|
||||
|
||||
def initdb():
|
||||
try:
|
||||
print 'creating db dir'
|
||||
print('creating db dir')
|
||||
os.mkdir(os.path.join(APPDIR, 'db'))
|
||||
except OSError:
|
||||
pass
|
||||
@@ -101,7 +100,7 @@ def printjieqi():
|
||||
res = query_db(sql)
|
||||
d = -75
|
||||
for row in res:
|
||||
print "%d: u'%s', " % (d, row[0])
|
||||
print("%d: u'%s', " % (d, row[0]))
|
||||
d += 15
|
||||
|
||||
|
||||
@@ -116,52 +115,17 @@ def query_db(query, args=(), one=False):
|
||||
return (rv[0] if rv else None) if one else rv
|
||||
|
||||
|
||||
class HTTPCompress(urllib2.BaseHandler):
|
||||
"""A handler to add gzip capabilities to urllib2 requests """
|
||||
def http_request(self, req):
|
||||
req.add_header("Accept-Encoding", "gzip, deflate")
|
||||
req.add_header("User-Agent",
|
||||
"Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.13) Gecko/20101203")
|
||||
return req
|
||||
|
||||
def http_response(self, req, resp):
|
||||
old_resp = resp
|
||||
if resp.headers.get("content-encoding") == "gzip":
|
||||
data = gzip.GzipFile(fileobj=StringIO(resp.read()), mode="r")
|
||||
resp = urllib2.addinfourl(data, old_resp.headers,
|
||||
old_resp.url, old_resp.code)
|
||||
resp.msg = old_resp.msg
|
||||
if resp.headers.get("content-encoding") == "deflate":
|
||||
data = zlib.decompress(resp.read(), -zlib.MAX_WBITS)
|
||||
resp = urllib2.addinfourl(data, old_resp.headers,
|
||||
old_resp.url, old_resp.code)
|
||||
resp.msg = old_resp.msg
|
||||
return resp
|
||||
|
||||
|
||||
def browser(proxy=None):
|
||||
gzip_support = HTTPCompress
|
||||
cj = cookielib.CookieJar()
|
||||
cookie_support = urllib2.HTTPCookieProcessor(cj)
|
||||
proxy_support = urllib2.ProxyHandler(proxy)
|
||||
if proxy:
|
||||
opener = urllib2.build_opener(gzip_support, urllib2.HTTPHandler,
|
||||
cookie_support, proxy_support)
|
||||
else:
|
||||
opener = urllib2.build_opener(gzip_support, urllib2.HTTPHandler,
|
||||
cookie_support)
|
||||
return opener
|
||||
|
||||
|
||||
def parse_hko(pageurl):
|
||||
''' parse lunar calendar from hk Obs
|
||||
Args: pageurl
|
||||
Return:
|
||||
a string contains all posts'''
|
||||
|
||||
print 'grabbing and parsing %s' % pageurl
|
||||
br = browser(PROXY)
|
||||
lines = br.open(pageurl).readlines()
|
||||
print('grabbing and parsing %s' % pageurl)
|
||||
with urllib.request.urlopen(pageurl) as f:
|
||||
html = f.read()
|
||||
lines = html.decode('big5').split('\n')
|
||||
|
||||
sql_nojq = ('insert or replace into ical (date,lunardate) '
|
||||
'values(?,?) ')
|
||||
sql_jq = ('insert or replace into ical (date,lunardate,jieqi) '
|
||||
@@ -169,7 +133,6 @@ def parse_hko(pageurl):
|
||||
conn = sqlite3.connect(DB_FILE)
|
||||
db = conn.cursor()
|
||||
for line in lines:
|
||||
line = line.decode('big5')
|
||||
m = RE_CAL.match(line)
|
||||
if m:
|
||||
fds = line.split()
|
||||
@@ -193,7 +156,7 @@ def parse_hko(pageurl):
|
||||
|
||||
def update_cal():
|
||||
''' fetch lunar calendar from HongKong Obs, parse it and save to db'''
|
||||
for y in xrange(1901, 2101):
|
||||
for y in range(1901, 2101):
|
||||
parse_hko(URL % y)
|
||||
|
||||
|
||||
@@ -209,15 +172,15 @@ def gen_cal(start, end, fp):
|
||||
endyear = int(end[:4])
|
||||
if startyear > 1900 and endyear < 2101:
|
||||
# use Lunar Calendar from HKO
|
||||
print 'use Lunar Calendar from HKO'
|
||||
print('use Lunar Calendar from HKO')
|
||||
sql = ('select date, lunardate, holiday, jieqi from ical '
|
||||
'where date>=? and date<=? order by date')
|
||||
rows = query_db(sql, (start, end))
|
||||
else:
|
||||
# compute Lunar Calendar by astronomical algorithm
|
||||
print 'compute Lunar Calendar by astronomical algorithm '
|
||||
print('compute Lunar Calendar by astronomical algorithm ')
|
||||
rows = []
|
||||
for year in xrange(startyear, endyear + 1):
|
||||
for year in range(startyear, endyear + 1):
|
||||
row = cn_lunarcal(year)
|
||||
rows.extend(row)
|
||||
|
||||
@@ -226,7 +189,7 @@ def gen_cal(start, end, fp):
|
||||
for r in rows:
|
||||
dt = datetime.strptime(r['date'], '%Y-%m-%d')
|
||||
|
||||
if r['lunardate'] in CN_MON.keys():
|
||||
if r['lunardate'] in list(CN_MON.keys()):
|
||||
ld = ['%s%s' % (lunaryear(r['date']), r['lunardate'])]
|
||||
else:
|
||||
ld = [r['lunardate']]
|
||||
@@ -239,12 +202,12 @@ def gen_cal(start, end, fp):
|
||||
utcstamp = datetime.utcnow().strftime('%Y%m%dT%H%M%SZ')
|
||||
line = ICAL_SEC % (utcstamp, uid, dt.strftime('%Y%m%d'),
|
||||
(dt + oneday).strftime('%Y%m%d'), summary)
|
||||
lines.append(line.encode('utf8'))
|
||||
lines.append(line)
|
||||
lines.append(ICAL_END)
|
||||
outputf = open(fp, 'w')
|
||||
outputf.write('\n'.join(lines))
|
||||
outputf.close()
|
||||
print 'iCal lunar calendar from %s to %s saved to %s' % (start, end, fp)
|
||||
print('iCal lunar calendar from %s to %s saved to %s' % (start, end, fp))
|
||||
|
||||
|
||||
def gen_cal_jieqi_only(start, end, fp):
|
||||
@@ -259,23 +222,21 @@ def gen_cal_jieqi_only(start, end, fp):
|
||||
endyear = int(end[:4])
|
||||
if startyear > 1900 and endyear < 2101:
|
||||
# use Lunar Calendar from HKO
|
||||
print 'use Lunar Calendar from HKO'
|
||||
print('use Lunar Calendar from HKO')
|
||||
sql = ('select date, lunardate, holiday, jieqi from ical '
|
||||
'where date>=? and date<=? order by date')
|
||||
rows = query_db(sql, (start, end))
|
||||
else:
|
||||
# compute Lunar Calendar by astronomical algorithm
|
||||
print 'compute Lunar Calendar by astronomical algorithm '
|
||||
print('compute Lunar Calendar by astronomical algorithm ')
|
||||
rows = []
|
||||
for year in xrange(startyear, endyear + 1):
|
||||
for year in range(startyear, endyear + 1):
|
||||
row = cn_lunarcal(year)
|
||||
rows.extend(row)
|
||||
|
||||
lines = [ICAL_HEAD]
|
||||
oneday = timedelta(days=1)
|
||||
for r in rows:
|
||||
dt = datetime.strptime(r['date'], '%Y-%m-%d')
|
||||
|
||||
if not r['holiday'] and not r['jieqi']:
|
||||
continue
|
||||
|
||||
@@ -287,14 +248,15 @@ def gen_cal_jieqi_only(start, end, fp):
|
||||
uid = '%s-lc@infinet.github.io' % r['date']
|
||||
summary = ' '.join(ld)
|
||||
utcstamp = datetime.utcnow().strftime('%Y%m%dT%H%M%SZ')
|
||||
dt = datetime.strptime(r['date'], '%Y-%m-%d')
|
||||
line = ICAL_SEC % (utcstamp, uid, dt.strftime('%Y%m%d'),
|
||||
(dt + oneday).strftime('%Y%m%d'), summary)
|
||||
lines.append(line.encode('utf8'))
|
||||
lines.append(line)
|
||||
lines.append(ICAL_END)
|
||||
outputf = open(fp, 'w')
|
||||
outputf.write('\n'.join(lines))
|
||||
outputf.close()
|
||||
print 'iCal Jieqi/Traditional Chinese holiday calendar from %s to %s saved to %s' % (start, end, fp)
|
||||
print('iCal Jieqi/Traditional Chinese holiday calendar from %s to %s saved to %s' % (start, end, fp))
|
||||
|
||||
|
||||
def post_process():
|
||||
@@ -308,8 +270,8 @@ def post_process():
|
||||
conn = sqlite3.connect(DB_FILE)
|
||||
db = conn.cursor()
|
||||
for d in HK_ERROR:
|
||||
print 'fix lunar date for %s' % d
|
||||
db.execute(sql_update, (u'三十', d))
|
||||
print('fix lunar date for %s' % d)
|
||||
db.execute(sql_update, ('三十', d))
|
||||
conn.commit()
|
||||
|
||||
|
||||
@@ -339,27 +301,27 @@ def update_holiday():
|
||||
continue
|
||||
|
||||
if m == 12 and d == 8:
|
||||
args.append((r['id'], u'腊八'))
|
||||
args.append((r['id'], '腊八'))
|
||||
elif m == 1 and d == 1:
|
||||
args.append((r['id'], u'春节'))
|
||||
args.append((previd, u'除夕'))
|
||||
args.append((r['id'], '春节'))
|
||||
args.append((previd, '除夕'))
|
||||
elif m == 1 and d == 15:
|
||||
args.append((r['id'], u'元宵'))
|
||||
args.append((r['id'], '元宵'))
|
||||
elif m == 5 and d == 5:
|
||||
args.append((r['id'], u'端午'))
|
||||
args.append((r['id'], '端午'))
|
||||
elif m == 7 and d == 7:
|
||||
args.append((r['id'], u'七夕'))
|
||||
args.append((r['id'], '七夕'))
|
||||
elif m == 7 and d == 15:
|
||||
args.append((r['id'], u'中元'))
|
||||
args.append((r['id'], '中元'))
|
||||
elif m == 8 and d == 15:
|
||||
args.append((r['id'], u'中秋'))
|
||||
args.append((r['id'], '中秋'))
|
||||
elif m == 9 and d == 9:
|
||||
args.append((r['id'], u'重阳'))
|
||||
args.append((r['id'], '重阳'))
|
||||
elif m == 10 and d == 15:
|
||||
args.append((r['id'], u'下元'))
|
||||
args.append((r['id'], '下元'))
|
||||
|
||||
if r['jieqi'] == u'清明':
|
||||
args.append((previd, u'寒食'))
|
||||
if r['jieqi'] == '清明':
|
||||
args.append((previd, '寒食'))
|
||||
previd = r['id']
|
||||
|
||||
sql_update = 'update ical set holiday=? where id=?'
|
||||
@@ -367,9 +329,9 @@ def update_holiday():
|
||||
db = conn.cursor()
|
||||
for arg in args:
|
||||
db.execute(sql_update, (arg[1], arg[0]))
|
||||
print 'update %s' % arg[1]
|
||||
print('update %s' % arg[1])
|
||||
conn.commit()
|
||||
print 'Chinese Traditional Holiday updated'
|
||||
print('Chinese Traditional Holiday updated')
|
||||
|
||||
|
||||
def ganzhi(lyear):
|
||||
@@ -383,7 +345,7 @@ def ganzhi(lyear):
|
||||
g = GAN[int(str(lyear)[-1])]
|
||||
z = ZHI[int(lyear) % 12]
|
||||
sx = SX[int(lyear) % 12]
|
||||
return u'%s%s[%s]' % (g, z, sx)
|
||||
return '%s%s[%s]' % (g, z, sx)
|
||||
|
||||
|
||||
def lunaryear(isodate):
|
||||
@@ -415,8 +377,8 @@ def main():
|
||||
opts, args = getopt.getopt(sys.argv[1:], 'h',
|
||||
['start=', 'end=', 'help', 'jieqi'])
|
||||
except getopt.GetoptError as err:
|
||||
print str(err)
|
||||
print helpmsg
|
||||
print(str(err))
|
||||
print(helpmsg)
|
||||
sys.exit(2)
|
||||
jieqionly = False
|
||||
for o, v in opts:
|
||||
@@ -460,7 +422,7 @@ def verify_lunarcalendar():
|
||||
start = 1949
|
||||
sql = 'select date, lunardate,jieqi from ical where date>=? and date<=?'
|
||||
while start < 2101:
|
||||
print 'compare %d' % start
|
||||
print('compare %d' % start)
|
||||
ystart = '%d-01-01' % start
|
||||
yend = '%d-12-31' % start
|
||||
res = query_db(sql, (ystart, yend))
|
||||
@@ -472,15 +434,15 @@ def verify_lunarcalendar():
|
||||
hko.append((x[0], x[1]))
|
||||
|
||||
aalc = cn_lunarcal(start)
|
||||
for i in xrange(len(aalc)):
|
||||
for i in range(len(aalc)):
|
||||
aaday, aaldate = aalc[i]['date'], aalc[i]['lunardate']
|
||||
if aalc[i]['jieqi']:
|
||||
aaldate = '%s %s' % (aalc[i]['lunardate'], aalc[i]['jieqi'])
|
||||
hkoday, hkoldate = hko[i]
|
||||
#print aaday, aaldate
|
||||
if aaday != hkoday or aaldate != hkoldate:
|
||||
print 'AA %s %s, HKO %s %s' % (aaday, aaldate, hkoday,
|
||||
hkoldate)
|
||||
print('AA %s %s, HKO %s %s' % (aaday, aaldate, hkoday,
|
||||
hkoldate))
|
||||
start += 1
|
||||
|
||||
|
||||
|
||||
106
lunarcalbase.py
106
lunarcalbase.py
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
''' generate Chinese Lunar Calendar by astronomical algorithms. Also mark the
|
||||
@@ -17,42 +17,42 @@ __all__ = ['cn_lunarcal']
|
||||
|
||||
LCSTARTMONTH = 11
|
||||
|
||||
CN_DAY = {2: u'初二', 3: u'初三', 4: u'初四', 5: u'初五', 6: u'初六',
|
||||
7: u'初七', 8: u'初八', 9: u'初九', 10: u'初十', 11: u'十一',
|
||||
12: u'十二', 13: u'十三', 14: u'十四', 15: u'十五', 16: u'十六',
|
||||
17: u'十七', 18: u'十八', 19: u'十九', 20: u'二十', 21: u'廿一',
|
||||
22: u'廿二', 23: u'廿三', 24: u'廿四', 25: u'廿五', 26: u'廿六',
|
||||
27: u'廿七', 28: u'廿八', 29: u'廿九', 30: u'三十'}
|
||||
CN_DAY = {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: '三十'}
|
||||
|
||||
CN_MON = {1: u'正月', 2: u'二月', 3: u'三月', 4: u'四月',
|
||||
5: u'五月', 6: u'六月', 7: u'七月', 8: u'八月',
|
||||
9: u'九月', 10: u'十月', 11: u'十一月', 12: u'十二月',
|
||||
CN_MON = {1: '正月', 2: '二月', 3: '三月', 4: '四月',
|
||||
5: '五月', 6: '六月', 7: '七月', 8: '八月',
|
||||
9: '九月', 10: '十月', 11: '十一月', 12: '十二月',
|
||||
|
||||
99: u'閏十一月', 100: u'閏十二月', 101: u'閏正月',
|
||||
102: u'閏二月', 103: u'閏三月', 104: u'閏四月',
|
||||
105: u'閏五月', 106: u'閏六月', 107: u'閏七月',
|
||||
108: u'閏八月', 109: u'閏九月', 110: u'閏十月',
|
||||
111: u'閏十一月', 112: u'閏十二月'}
|
||||
99: '閏十一月', 100: '閏十二月', 101: '閏正月',
|
||||
102: '閏二月', 103: '閏三月', 104: '閏四月',
|
||||
105: '閏五月', 106: '閏六月', 107: '閏七月',
|
||||
108: '閏八月', 109: '閏九月', 110: '閏十月',
|
||||
111: '閏十一月', 112: '閏十二月'}
|
||||
|
||||
CN_SOLARTERM = {-120: u'小雪',-105: u'大雪',
|
||||
-90: u'冬至', -75: u'小寒', -60: u'大寒',
|
||||
-45: u'立春', -30: u'雨水', -15: u'惊蛰',
|
||||
0: u'春分', 15: u'清明', 30: u'谷雨',
|
||||
45: u'立夏', 60: u'小满', 75: u'芒种',
|
||||
90: u'夏至', 105: u'小暑', 120: u'大暑',
|
||||
135: u'立秋', 150: u'处暑', 165: u'白露',
|
||||
180: u'秋分', 195: u'寒露', 210: u'霜降',
|
||||
225: u'立冬', 240: u'小雪', 255: u'大雪', 270: u'冬至'}
|
||||
CN_SOLARTERM = {-120: '小雪',-105: '大雪',
|
||||
-90: '冬至', -75: '小寒', -60: '大寒',
|
||||
-45: '立春', -30: '雨水', -15: '惊蛰',
|
||||
0: '春分', 15: '清明', 30: '谷雨',
|
||||
45: '立夏', 60: '小满', 75: '芒种',
|
||||
90: '夏至', 105: '小暑', 120: '大暑',
|
||||
135: '立秋', 150: '处暑', 165: '白露',
|
||||
180: '秋分', 195: '寒露', 210: '霜降',
|
||||
225: '立冬', 240: '小雪', 255: '大雪', 270: '冬至'}
|
||||
|
||||
CN_SOLARTERM = {-120: u'小雪',-105: u'大雪',
|
||||
-90: u'冬至', -75: u'小寒', -60: u'大寒',
|
||||
-45: u'立春', -30: u'雨水', -15: u'驚蟄',
|
||||
0: u'春分', 15: u'清明', 30: u'穀雨',
|
||||
45: u'立夏', 60: u'小滿', 75: u'芒種',
|
||||
90: u'夏至', 105: u'小暑', 120: u'大暑',
|
||||
135: u'立秋', 150: u'處暑', 165: u'白露',
|
||||
180: u'秋分', 195: u'寒露', 210: u'霜降',
|
||||
225: u'立冬', 240: u'小雪', 255: u'大雪', 270: u'冬至'}
|
||||
CN_SOLARTERM = {-120: '小雪',-105: '大雪',
|
||||
-90: '冬至', -75: '小寒', -60: '大寒',
|
||||
-45: '立春', -30: '雨水', -15: '驚蟄',
|
||||
0: '春分', 15: '清明', 30: '穀雨',
|
||||
45: '立夏', 60: '小滿', 75: '芒種',
|
||||
90: '夏至', 105: '小暑', 120: '大暑',
|
||||
135: '立秋', 150: '處暑', 165: '白露',
|
||||
180: '秋分', 195: '寒露', 210: '霜降',
|
||||
225: '立冬', 240: '小雪', 255: '大雪', 270: '冬至'}
|
||||
|
||||
|
||||
# calendar for this and next year are combined to generate the final output
|
||||
@@ -90,9 +90,9 @@ def find_astro(year):
|
||||
aadays.sort()
|
||||
|
||||
# normalize all Julian Day to midnight for later compare
|
||||
aadays = [(jdptime(jdftime(d[0], '%y-%m-%d', tz=8, ut=True), '%y-%m-%d'),
|
||||
tmp = [(jdptime(jdftime(d[0], '%y-%m-%d', tz=8, ut=True), '%y-%m-%d'),
|
||||
d[1]) for d in aadays]
|
||||
astro = [{'date': d[0], 'astro': d[1], 'month': None} for d in aadays]
|
||||
astro = [{'date': d[0], 'astro': d[1], 'month': None} for d in tmp]
|
||||
return astro
|
||||
|
||||
|
||||
@@ -118,7 +118,7 @@ def mark_lunarcal_month(clc):
|
||||
# mark month name, 11 is the month contains Winter Solstice
|
||||
newmoondate = [d['date'] for d in clc if d['astro'] == 'newmoon']
|
||||
mname = 11
|
||||
for i in xrange(len(newmoondate) - 1):
|
||||
for i in range(len(newmoondate) - 1):
|
||||
thisnm, nextnm = newmoondate[i], newmoondate[i + 1]
|
||||
if thisnm < lcstart:
|
||||
continue
|
||||
@@ -155,7 +155,7 @@ def scan_leap(clc):
|
||||
# leap year has more than 12 newmoons between two Winter Solstice
|
||||
if nmcount > 12:
|
||||
# search leap month from LC 11, to next LC 11, which = 11 + 13
|
||||
for m in xrange(11, 25):
|
||||
for m in range(11, 25):
|
||||
foundleap = True
|
||||
for d in clc:
|
||||
if d['astro'] == 'newmoon':
|
||||
@@ -229,30 +229,30 @@ def mark_holiday(clcdays):
|
||||
|
||||
'''
|
||||
|
||||
for i in xrange(len(clcdays)):
|
||||
for i in range(len(clcdays)):
|
||||
m, d = clcdays[i]['month'], clcdays[i]['day']
|
||||
if m == 12 and d == 8:
|
||||
clcdays[i]['holiday'] = u'腊八'
|
||||
clcdays[i]['holiday'] = '腊八'
|
||||
elif m == 1 and d == 1:
|
||||
clcdays[i]['holiday'] = u'春节'
|
||||
clcdays[i - 1]['holiday'] = u'除夕'
|
||||
clcdays[i]['holiday'] = '春节'
|
||||
clcdays[i - 1]['holiday'] = '除夕'
|
||||
elif m == 1 and d == 15:
|
||||
clcdays[i]['holiday'] = u'元宵'
|
||||
clcdays[i]['holiday'] = '元宵'
|
||||
elif m == 5 and d == 5:
|
||||
clcdays[i]['holiday'] = u'端午'
|
||||
clcdays[i]['holiday'] = '端午'
|
||||
elif m == 7 and d == 7:
|
||||
clcdays[i]['holiday'] = u'七夕'
|
||||
clcdays[i]['holiday'] = '七夕'
|
||||
elif m == 7 and d == 15:
|
||||
clcdays[i]['holiday'] = u'中元'
|
||||
clcdays[i]['holiday'] = '中元'
|
||||
elif m == 8 and d == 15:
|
||||
clcdays[i]['holiday'] = u'中秋'
|
||||
clcdays[i]['holiday'] = '中秋'
|
||||
elif m == 9 and d == 9:
|
||||
clcdays[i]['holiday'] = u'重阳'
|
||||
clcdays[i]['holiday'] = '重阳'
|
||||
elif m == 10 and d == 15:
|
||||
clcdays[i]['holiday'] = u'下元'
|
||||
clcdays[i]['holiday'] = '下元'
|
||||
|
||||
if clcdays[i]['jieqi'] == u'清明':
|
||||
clcdays[i - 1]['holiday'] = u'寒食'
|
||||
if clcdays[i]['jieqi'] == '清明':
|
||||
clcdays[i - 1]['holiday'] = '寒食'
|
||||
|
||||
return clcdays
|
||||
|
||||
@@ -302,13 +302,13 @@ def cn_lunarcal(year):
|
||||
|
||||
cal0 = search_lunarcal(year)
|
||||
cal1 = search_lunarcal(year + 1)
|
||||
for k, v in cal1.iteritems():
|
||||
for k, v in cal1.items():
|
||||
cal0[k] = v
|
||||
|
||||
start = jdptime('%s-%s-%s' % (year, 1, 1), '%y-%m-%d')
|
||||
end = jdptime('%s-%s-%s' % (year, 12, 31), '%y-%m-%d')
|
||||
lc = []
|
||||
for jd, day in cal0.iteritems():
|
||||
for jd, day in cal0.items():
|
||||
day['date'] = jdftime(jd, '%y-%m-%d', ut=False)
|
||||
if jd >= start and jd <= end:
|
||||
lc.append((jd, day))
|
||||
@@ -322,7 +322,7 @@ def cn_lunarcal(year):
|
||||
def main():
|
||||
a = cn_lunarcal(2033)
|
||||
for x in a:
|
||||
print x['date'], x['lunardate'], x['jieqi'], x['holiday']
|
||||
print(x['date'], x['lunardate'], x['jieqi'], x['holiday'])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
Reference in New Issue
Block a user