port from Python 2 to Python 3

This commit is contained in:
Chen Wei
2020-02-21 22:01:20 -06:00
parent 4b0a8aafd7
commit ae3d5d3208
5 changed files with 190 additions and 235 deletions

View File

@@ -22,7 +22,7 @@ calendar, thunderbird + lightning插件, iphone/ipad, 安卓都支持。
### 系统要求 ### 系统要求
* Python: python 2.7上测试可用 * Python: python 3.5上测试可用
* [Numpy][] 和 [Numexpr][]: 纯Python速度较慢而天文算法特别是完全版的VSOP87和LEA-406计算量尤其大所以最好配合Numpy以加快计算速度。 * [Numpy][] 和 [Numexpr][]: 纯Python速度较慢而天文算法特别是完全版的VSOP87和LEA-406计算量尤其大所以最好配合Numpy以加快计算速度。
@@ -120,7 +120,7 @@ of using their conversion table, which is only for Non-Commercial use.
### Requirement: ### Requirement:
* Python: tested on python 2.7 * Python: tested on python 3.5
* [Numpy][] and [Numexpr][]: Only needed when generate calendar by astronomical * [Numpy][] and [Numexpr][]: Only needed when generate calendar by astronomical
algorithm. The full version of LEA-406 and VSOP87 is rather slow when compute algorithm. The full version of LEA-406 and VSOP87 is rather slow when compute

130
aa.py
View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python #!/usr/bin/env python3
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
''' Implement astronomical algorithms for finding solar terms and moon phases. ''' Implement astronomical algorithms for finding solar terms and moon phases.
@@ -20,9 +20,11 @@ __license__ = 'BSD'
__copyright__ = '2020, Chen Wei <weichen302@gmail.com>' __copyright__ = '2020, Chen Wei <weichen302@gmail.com>'
__version__ = '0.0.3' __version__ = '0.0.3'
from numpy import * import math
import numexpr as ne from math import sin,cos,pi
import re import re
import numpy as np
import numexpr as ne
J2000 = 2451545.0 J2000 = 2451545.0
SYNODIC_MONTH = 29.53 SYNODIC_MONTH = 29.53
@@ -40,7 +42,7 @@ TWOPI = 2 * pi
# #
# Luni-Solar argument multipliers, coefficients, unit 1e-7 arcsec # Luni-Solar argument multipliers, coefficients, unit 1e-7 arcsec
# L L' F D Om longitude (sin, t*sin, cos), obliquity (cos, t*cos, sin) # 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, 0, 0, 1, -172064161, -174666, 33386, 92052331, 9086, 15377 ],
[ 0, 0, 2, -2, 2, -13170906, -1675, -13696, 5730336, -3015, -4587 ], [ 0, 0, 2, -2, 2, -13170906, -1675, -13696, 5730336, -3015, -4587 ],
[ 0, 0, 2, 0, 2, -2276413, -234, 2796, 978459, -485, 1374 ], [ 0, 0, 2, 0, 2, -2276413, -234, 2796, 978459, -485, 1374 ],
@@ -121,7 +123,7 @@ IAU2000BNutationTable = array([
]) ])
# Truncated VSOP87D tables # Truncated VSOP87D tables
earth_L0 = array([ earth_L0 = np.array([
[ 1.75347045673, 0, 0 ], [ 1.75347045673, 0, 0 ],
[ 0.03341656456, 4.66925680417, 6283.0758499914 ], [ 0.03341656456, 4.66925680417, 6283.0758499914 ],
[ 0.00034894275, 4.62610241759, 12566.1516999828 ], [ 0.00034894275, 4.62610241759, 12566.1516999828 ],
@@ -297,7 +299,7 @@ earth_L0 = array([
# 172 terms retained # 172 terms retained
]) ])
earth_L1 = array([ earth_L1 = np.array([
[ 6283.31966747491, 0, 0 ], [ 6283.31966747491, 0, 0 ],
[ 0.00206058863, 2.67823455584, 6283.0758499914 ], [ 0.00206058863, 2.67823455584, 6283.0758499914 ],
[ 0.0000430343, 2.63512650414, 12566.1516999828 ], [ 0.0000430343, 2.63512650414, 12566.1516999828 ],
@@ -466,7 +468,7 @@ earth_L1 = array([
# 165 terms retained # 165 terms retained
]) ])
earth_L2 = array([ earth_L2 = np.array([
[ 0.0005291887, 0, 0 ], [ 0.0005291887, 0, 0 ],
[ 0.00008719837, 1.07209665242, 6283.0758499914 ], [ 0.00008719837, 1.07209665242, 6283.0758499914 ],
[ 0.00000309125, 0.86728818832, 12566.1516999828 ], [ 0.00000309125, 0.86728818832, 12566.1516999828 ],
@@ -563,7 +565,7 @@ earth_L2 = array([
# 93 terms retained # 93 terms retained
]) ])
earth_L3 = array([ earth_L3 = np.array([
[ 0.00000289226, 5.84384198723, 6283.0758499914 ], [ 0.00000289226, 5.84384198723, 6283.0758499914 ],
[ 0.00000034955, 0, 0 ], [ 0.00000034955, 0, 0 ],
[ 0.00000016819, 5.48766912348, 12566.1516999828 ], [ 0.00000016819, 5.48766912348, 12566.1516999828 ],
@@ -575,7 +577,7 @@ earth_L3 = array([
# 8 terms retained # 8 terms retained
]) ])
earth_L4 = array([ earth_L4 = np.array([
[ 0.00000114084, 3.14159265359, 0 ], [ 0.00000114084, 3.14159265359, 0 ],
[ 0.00000007717, 4.13446589358, 6283.0758499914 ], [ 0.00000007717, 4.13446589358, 6283.0758499914 ],
[ 0.00000000765, 3.83803776214, 12566.1516999828 ], [ 0.00000000765, 3.83803776214, 12566.1516999828 ],
@@ -583,7 +585,7 @@ earth_L4 = array([
# 4 terms retained # 4 terms retained
]) ])
earth_L5 = array([ earth_L5 = np.array([
[ 0.00000000878, 3.14159265359, 0 ], [ 0.00000000878, 3.14159265359, 0 ],
[ 0.00000000172, 2.7657906951, 6283.0758499914 ], [ 0.00000000172, 2.7657906951, 6283.0758499914 ],
[ 0.0000000005, 2.01353298182, 155.4203994342 ], [ 0.0000000005, 2.01353298182, 155.4203994342 ],
@@ -591,7 +593,7 @@ earth_L5 = array([
# 4 terms retained # 4 terms retained
]) ])
earth_B0 = array([ earth_B0 = np.array([
[ 0.0000027962, 3.19870156017, 84334.66158130829 ], [ 0.0000027962, 3.19870156017, 84334.66158130829 ],
[ 0.00000101643, 5.42248619256, 5507.5532386674 ], [ 0.00000101643, 5.42248619256, 5507.5532386674 ],
[ 0.00000080445, 3.88013204458, 5223.6939198022 ], [ 0.00000080445, 3.88013204458, 5223.6939198022 ],
@@ -615,7 +617,7 @@ earth_B0 = array([
# 20 terms retained # 20 terms retained
]) ])
earth_B1 = array([ earth_B1 = np.array([
[ 0.0000000903, 3.8972906189, 5507.5532386674 ], [ 0.0000000903, 3.8972906189, 5507.5532386674 ],
[ 0.00000006177, 1.73038850355, 5223.6939198022 ], [ 0.00000006177, 1.73038850355, 5223.6939198022 ],
[ 0.000000038, 5.24404145734, 2352.8661537718 ], [ 0.000000038, 5.24404145734, 2352.8661537718 ],
@@ -631,7 +633,7 @@ earth_B1 = array([
# 12 terms retained # 12 terms retained
]) ])
earth_B2 = array([ earth_B2 = np.array([
[ 0.00000001662, 1.62703209173, 84334.66158130829 ], [ 0.00000001662, 1.62703209173, 84334.66158130829 ],
[ 0.00000000492, 2.41382223971, 1047.7473117547 ], [ 0.00000000492, 2.41382223971, 1047.7473117547 ],
[ 0.00000000344, 2.24353004539, 5507.5532386674 ], [ 0.00000000344, 2.24353004539, 5507.5532386674 ],
@@ -639,17 +641,17 @@ earth_B2 = array([
# 4 terms retained # 4 terms retained
]) ])
earth_B3 = array([ earth_B3 = np.array([
[ 0, 0, 0 ], [ 0, 0, 0 ],
# 0 terms retained # 0 terms retained
]) ])
earth_B4 = array([ earth_B4 = np.array([
[ 0, 0, 0 ], [ 0, 0, 0 ],
# 0 terms retained # 0 terms retained
]) ])
earth_R0 = array([ earth_R0 = np.array([
[ 1.00013988799, 0, 0 ], [ 1.00013988799, 0, 0 ],
[ 0.01670699626, 3.09846350771, 6283.0758499914 ], [ 0.01670699626, 3.09846350771, 6283.0758499914 ],
[ 0.00013956023, 3.0552460962, 12566.1516999828 ], [ 0.00013956023, 3.0552460962, 12566.1516999828 ],
@@ -725,7 +727,7 @@ earth_R0 = array([
# 72 terms retained # 72 terms retained
]) ])
earth_R1 = array([ earth_R1 = np.array([
[ 0.00103018608, 1.10748969588, 6283.0758499914 ], [ 0.00103018608, 1.10748969588, 6283.0758499914 ],
[ 0.00001721238, 1.06442301418, 12566.1516999828 ], [ 0.00001721238, 1.06442301418, 12566.1516999828 ],
[ 0.00000702215, 3.14159265359, 0 ], [ 0.00000702215, 3.14159265359, 0 ],
@@ -739,7 +741,7 @@ earth_R1 = array([
# 10 terms retained # 10 terms retained
]) ])
earth_R2 = array([ earth_R2 = np.array([
[ 0.00004359385, 5.78455133738, 6283.0758499914 ], [ 0.00004359385, 5.78455133738, 6283.0758499914 ],
[ 0.00000123633, 5.57934722157, 12566.1516999828 ], [ 0.00000123633, 5.57934722157, 12566.1516999828 ],
[ 0.00000012341, 3.14159265359, 0 ], [ 0.00000012341, 3.14159265359, 0 ],
@@ -749,18 +751,18 @@ earth_R2 = array([
# 6 terms retained # 6 terms retained
]) ])
earth_R3 = array([ earth_R3 = np.array([
[ 0.00000144595, 4.27319435148, 6283.0758499914 ], [ 0.00000144595, 4.27319435148, 6283.0758499914 ],
[ 0.00000006729, 3.91697608662, 12566.1516999828 ], [ 0.00000006729, 3.91697608662, 12566.1516999828 ],
# 2 terms retained # 2 terms retained
]) ])
earth_R4 = array([ earth_R4 = np.array([
[ 0.00000003858, 2.56384387339, 6283.0758499914 ], [ 0.00000003858, 2.56384387339, 6283.0758499914 ],
# 1 terms retained # 1 terms retained
]) ])
earth_R5 = array([ earth_R5 = np.array([
[ 0, 0, 0 ], [ 0, 0, 0 ],
# 0 terms retained # 0 terms retained
]) ])
@@ -774,7 +776,7 @@ earth_R5 = array([
# terms of 3rd-degree and 4th-degree are ignored # terms of 3rd-degree and 4th-degree are ignored
# in arcsec # in arcsec
# average error Moon = 0.73", max 1.5" # average error Moon = 0.73", max 1.5"
M_ARG = array([ M_ARG = np.array([
# 226 terms # 226 terms
[ 485868.249036, 1717915923.21779990, 31.87920 ], [ 485868.249036, 1717915923.21779990, 31.87920 ],
[ 1658653.158348, 1488007279.20020032, -44.62040 ], [ 1658653.158348, 1488007279.20020032, -44.62040 ],
@@ -1009,7 +1011,7 @@ M_ARG = array([
# Ak1 mas/yr Amplitude of the 1st-order Poisson term # Ak1 mas/yr Amplitude of the 1st-order Poisson term
# Ak2 uas/yr2 Amplitude of the 2nd-order Poisson term # Ak2 uas/yr2 Amplitude of the 2nd-order Poisson term
# [ Ak0, Ak1, Ak2 ] ... # [ Ak0, Ak1, Ak2 ] ...
M_AMP = array([ M_AMP = np.array([
# 226 terms # 226 terms
[ 22639.5864251, 0.190648, 5.529914 ], [ 22639.5864251, 0.190648, 5.529914 ],
[ 4586.4946082, 0.112352, 1.480719 ], [ 4586.4946082, 0.112352, 1.480719 ],
@@ -1244,7 +1246,7 @@ M_AMP = array([
# phik1 arcsec Phase of the 1st-order Poisson term # phik1 arcsec Phase of the 1st-order Poisson term
# phik2 arcsec Phase of the 2nd-order Poisson term # phik2 arcsec Phase of the 2nd-order Poisson term
# [ phik0, phik1, phik2 ] ... # [ phik0, phik1, phik2 ] ...
M_PHASE = array([ M_PHASE = np.array([
# 226 terms # 226 terms
[ 0.000383901368, -85.864631587374, -90.051320519700 ], [ 0.000383901368, -85.864631587374, -90.051320519700 ],
[ 0.002465002781, 43.853451435402, -89.760808801732 ], [ 0.002465002781, 43.853451435402, -89.760808801732 ],
@@ -1476,16 +1478,16 @@ M_PHASE = array([
# post process of LEA-406 tables # post process of LEA-406 tables
# horizontal split the numpy array # 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 CV = M_PHASE * DEG2RAD
C_V, CT_V, CTT_V = hsplit(CV, 3) C_V, CT_V, CTT_V = np.hsplit(CV, 3)
A_V, AT_V, ATT_V = hsplit(M_AMP, 3) A_V, AT_V, ATT_V = np.hsplit(M_AMP, 3)
def vsopLx(vsopterms, t): def vsopLx(vsopterms, t):
''' helper function for calculate VSOP87 ''' ''' 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) return sum(lx)
@@ -1520,18 +1522,6 @@ def vsop(jde, FK5=True):
lon = (L0 + t * (L1 + t * (L2 + t * (L3 + t * (L4 + t * L5))))) lon = (L0 + t * (L1 + t * (L2 + t * (L3 + t * (L4 + t * L5)))))
if FK5: 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 deltalon = -4.379321981462438e-07
lon += deltalon lon += deltalon
@@ -1555,7 +1545,7 @@ def rootbysecand(f, angle, x0, x1, precision=0.000000001):
def normrad(r): def normrad(r):
''' covernt radian to 0 - 2pi ''' ''' covernt radian to 0 - 2pi '''
alpha = fmod(r, TWOPI) alpha = math.fmod(r, TWOPI)
if alpha < 0: if alpha < 0:
alpha += TWOPI alpha += TWOPI
return alpha return alpha
@@ -1563,7 +1553,7 @@ def normrad(r):
def npitopi(r): def npitopi(r):
''' convert an angle in radians into (-pi, +pi] ''' ''' convert an angle in radians into (-pi, +pi] '''
r = fmod(r, TWOPI) r = math.fmod(r, TWOPI)
if r > PI: if r > PI:
r -= TWOPI r -= TWOPI
elif r <= -1.0 * PI: elif r <= -1.0 * PI:
@@ -1582,7 +1572,7 @@ def fmtdeg(fdegree):
sign ='' sign =''
if fdegree < 0: if fdegree < 0:
sign = '-' 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) math.floor(minutes), secs)
return res return res
@@ -1689,8 +1679,8 @@ def findnewmoons(start, count=15):
b = newmoon(start) b = newmoon(start)
if b != nm: if b != nm:
if nm > 0 and abs(nm - b) > (SYNODIC_MONTH + 1): if nm > 0 and abs(nm - b) > (SYNODIC_MONTH + 1):
print 'last newmoon %s, found %s' % (fmtjde2ut(nm), print('last newmoon %s, found %s' % (fmtjde2ut(nm),
fmtjde2ut(b)) fmtjde2ut(b)))
newmoons.append(b) newmoons.append(b)
nm = b nm = b
nmcount += 1 nmcount += 1
@@ -1753,8 +1743,8 @@ def lightabbr_low(jde):
# Sun's distance from the Earth, in AU # Sun's distance from the Earth, in AU
#R = (1.000001018 * (1 - e * e)) / (1 + e * cos(math.radians(v))) #R = (1.000001018 * (1 - e * e)) / (1 + e * cos(math.radians(v)))
# finally, the aberration in radians # finally, the aberration in radians
labbr = (math.radians(20.49552 / 3600.0) * (1 + e * cos(math.radians(v))) / labbr = (math.radians(20.49552 / 3600.0)
-1.000001018) * (1 + e * math.cos(math.radians(v))) / -1.000001018)
return labbr return labbr
@@ -1886,7 +1876,7 @@ def jd2g(jd):
jd += 0.5 jd += 0.5
z = int(jd) z = int(jd)
f = fmod(jd, 1.0) # decimal part f = math.fmod(jd, 1.0) # decimal part
if z < 2299161: if z < 2299161:
a = z a = z
else: else:
@@ -2187,10 +2177,10 @@ def nutation(jde):
#Mean longitude of the ascending node of the Moon. #Mean longitude of the ascending node of the Moon.
Om = 450160.398036 - t * 6962890.5431 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) 11)
args = (m1 * L + m2 * Lp + m3 * F + m4 * D + m5 * Om) * ASEC2RAD 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 # unit of longitude is 1.0e-7 arcsec, convert it to arcsec
lon *= 1.0e-7 lon *= 1.0e-7
@@ -2201,7 +2191,7 @@ def nutation(jde):
lon += deplan lon += deplan
lon *= ASEC2RAD # Convert from arcsec to radians lon *= ASEC2RAD # Convert from arcsec to radians
lon = fmod(lon, TWOPI) lon = math.fmod(lon, TWOPI)
return lon return lon
@@ -2236,7 +2226,7 @@ def fortran_readline(line, fmt):
tmp = [] tmp = []
i = 0 i = 0
for rep, ftype, length in fw: for rep, ftype, length in fw:
for cnt in xrange(rep): for cnt in range(rep):
field = line[i: i + length] field = line[i: i + length]
i += length i += length
if ftype == 'F': if ftype == 'F':
@@ -2261,7 +2251,7 @@ def fortran_read(fp, fmt):
tmp = [] tmp = []
i = 0 i = 0
for rep, ftype, length in fw: for rep, ftype, length in fw:
for cnt in xrange(rep): for cnt in range(rep):
field = line[i: i + length] field = line[i: i + length]
i += length i += length
if ftype == 'F': if ftype == 'F':
@@ -2391,7 +2381,7 @@ class LEA406():
CTT_V.append(a[20]) CTT_V.append(a[20])
# CALCULATING THE ARGUMENTS [RAD] # CALCULATING THE ARGUMENTS [RAD]
for K in xrange(14): for K in range(14):
F0_V[I] += IND[K] * FR[K][0] F0_V[I] += IND[K] * FR[K][0]
F1_V[I] += IND[K] * FR[K][1] F1_V[I] += IND[K] * FR[K][1]
F2_V[I] += IND[K] * FR[K][2] F2_V[I] += IND[K] * FR[K][2]
@@ -2399,19 +2389,19 @@ class LEA406():
F4_V[I] += IND[K] * FR[K][4] F4_V[I] += IND[K] * FR[K][4]
LEN_KEPT = LEN - count LEN_KEPT = LEN - count
print '%d skipped, %d kept' % (count, LEN_KEPT) print('%d skipped, %d kept' % (count, LEN_KEPT))
self.A_V =array(A_V) self.A_V =np.array(A_V)
self.AT_V =array(AT_V) self.AT_V =np.array(AT_V)
self.ATT_V =array(ATT_V) self.ATT_V =np.array(ATT_V)
self.C_V =array(C_V) * DEG2RAD self.C_V =np.array(C_V) * DEG2RAD
self.CT_V =array(CT_V) * DEG2RAD self.CT_V =np.array(CT_V) * DEG2RAD
self.CTT_V =array(CTT_V) * DEG2RAD self.CTT_V =np.array(CTT_V) * DEG2RAD
self.F0_V = array(F0_V) * 3600 self.F0_V = np.array(F0_V) * 3600
self.F1_V = array(F1_V) self.F1_V = np.array(F1_V)
self.F2_V = array(F2_V) self.F2_V = np.array(F2_V)
self.F3_V = array(F3_V) self.F3_V = np.array(F3_V)
self.F4_V = array(F4_V) self.F4_V = np.array(F4_V)
self.I_V = I self.I_V = I
def lon(self, jd, ignorenutation=False): def lon(self, jd, ignorenutation=False):
@@ -2480,11 +2470,11 @@ def main():
#jd = 2444239.5 #jd = 2444239.5
jd = g2jd(1900, 1, 1) jd = g2jd(1900, 1, 1)
#lea406class = LEA406() #lea406class = LEA406()
for i in xrange(1): for i in range(1):
#l = normrad(lea406class.lon(jd)) #l = normrad(lea406class.lon(jd))
l = normrad(lea406(jd)) l = normrad(lea406(jd))
#d = fmtdeg(math.degrees(npitopi(e -l ))) #d = fmtdeg(math.degrees(npitopi(e -l )))
print jd, l, fmtdeg(math.degrees(l)) print((jd, l, fmtdeg(math.degrees(l))))
jd += 2000 jd += 2000
#print fmtdeg(math.degrees(e) % 360.0) #print fmtdeg(math.degrees(e) % 360.0)
#angle = -105 #angle = -105
@@ -2497,8 +2487,8 @@ def main():
def test(): def test():
jd = 2411545.0 jd = 2411545.0
year = 2097 year = 2097
for year in xrange(2060, 2060): for year in range(2060, 2060):
print year, deltaT(year, 9) print(year, deltaT(year, 9))
if __name__ == "__main__": if __name__ == "__main__":

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python #!/usr/bin/env python3
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
''' Implement astronomical algorithms for finding solar terms and moon phases. ''' Implement astronomical algorithms for finding solar terms and moon phases.
@@ -20,7 +20,10 @@ __license__ = 'BSD'
__copyright__ = '2020, Chen Wei <weichen302@gmail.com>' __copyright__ = '2020, Chen Wei <weichen302@gmail.com>'
__version__ = '0.0.3' __version__ = '0.0.3'
from numpy import * import math
from math import pi, fmod
import numpy as np
import numexpr as ne import numexpr as ne
from aa import lightabbr_high from aa import lightabbr_high
from aa import nutation from aa import nutation
@@ -41,7 +44,7 @@ TWOPI = 2 * pi
def vsopLx(vsopterms, t): def vsopLx(vsopterms, t):
''' helper function for calculate VSOP87 ''' ''' 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) 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 from aa_full_table import M_ARG, M_AMP, M_PHASE
# post import process of LEA-406 tables, horizontal split the numpy array # 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 CV = M_PHASE * DEG2RAD
C_V, CT_V, CTT_V = hsplit(CV, 3) C_V, CT_V, CTT_V = np.hsplit(CV, 3)
A_V, AT_V, ATT_V = hsplit(M_AMP, 3) A_V, AT_V, ATT_V = np.hsplit(M_AMP, 3)
def lea406_full(jd, ignorenutation=False): def lea406_full(jd, ignorenutation=False):
@@ -322,10 +325,10 @@ def lea406_full(jd, ignorenutation=False):
def main(): def main():
#jd = 2444239.5 #jd = 2444239.5
jd = g2jd(1900, 1, 1) jd = g2jd(1900, 1, 1)
for i in xrange(10): for i in range(10):
l = normrad(lea406_full(jd)) l = normrad(lea406_full(jd))
#d = fmtdeg(math.degrees(npitopi(e -l ))) #d = fmtdeg(math.degrees(npitopi(e -l )))
print jd, l, fmtdeg(math.degrees(l)) print(jd, l, fmtdeg(math.degrees(l)))
jd += 2000 jd += 2000
#print fmtdeg(math.degrees(e) % 360.0) #print fmtdeg(math.degrees(e) % 360.0)
#angle = -105 #angle = -105

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python #!/usr/bin/env python3
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
'''get lunar calendar from hk observatory '''get lunar calendar from hk observatory
@@ -12,23 +12,22 @@ __license__ = 'BSD'
__copyright__ = '2020, Chen Wei <weichen302@gmail.com>' __copyright__ = '2020, Chen Wei <weichen302@gmail.com>'
__version__ = '0.0.3' __version__ = '0.0.3'
from StringIO import StringIO from io import StringIO
from datetime import datetime from datetime import datetime
from datetime import timedelta from datetime import timedelta
import cookielib
import getopt import getopt
import gzip import gzip
import os import os
import re import re
import sqlite3 import sqlite3
import sys import sys
import urllib2 import urllib.request
import zlib import zlib
from lunarcalbase import cn_lunarcal from lunarcalbase import cn_lunarcal
APPDIR = os.path.abspath(os.path.dirname(__file__)) APPDIR = os.path.abspath(os.path.dirname(__file__))
DB_FILE = os.path.join(APPDIR, 'db', 'lunarcal.sqlite') 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 = {'http': 'http://localhost:8001'}
PROXY = None PROXY = None
URL = 'https://www.hko.gov.hk/tc/gts/time/calendar/text/files/T%dc.txt' 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' ICAL_END = 'END:VCALENDAR'
CN_DAY = {u'初二': 2, u'初三': 3, u'初四': 4, u'初五': 5, u'初六': 6, CN_DAY = {'初二': 2, '初三': 3, '初四': 4, '初五': 5, '初六': 6,
u'初七': 7, u'初八': 8, u'初九': 9, u'初十': 10, u'十一': 11, '初七': 7, '初八': 8, '初九': 9, '初十': 10, '十一': 11,
u'十二': 12, u'十三': 13, u'十四': 14, u'十五': 15, u'十六': 16, '十二': 12, '十三': 13, '十四': 14, '十五': 15, '十六': 16,
u'十七': 17, u'十八': 18, u'十九': 19, u'二十': 20, u'廿一': 21, '十七': 17, '十八': 18, '十九': 19, '二十': 20, '廿一': 21,
u'廿二': 22, u'廿三': 23, u'廿四': 24, u'廿五': 25, u'廿六': 26, '廿二': 22, '廿三': 23, '廿四': 24, '廿五': 25, '廿六': 26,
u'廿七': 27, u'廿八': 28, u'廿九': 29, u'三十': 30} '廿七': 27, '廿八': 28, '廿九': 29, '三十': 30}
CN_MON = {u'正月': 1, u'二月': 2, u'三月': 3, u'四月': 4, CN_MON = {'正月': 1, '二月': 2, '三月': 3, '四月': 4,
u'五月': 5, u'六月': 6, u'七月': 7, u'八月': 8, '五月': 5, '六月': 6, '七月': 7, '八月': 8,
u'九月': 9, u'十月': 10, u'十一月': 11, u'十二月': 12, '九月': 9, '十月': 10, '十一月': 11, '十二月': 12,
u'閏正月': 101, u'閏二月': 102, u'閏三月': 103, u'閏四月': 104, '閏正月': 101, '閏二月': 102, '閏三月': 103, '閏四月': 104,
u'閏五月': 105, u'閏六月': 106, u'閏七月': 107, u'閏八月': 108, '閏五月': 105, '閏六月': 106, '閏七月': 107, '閏八月': 108,
u'閏九月': 109, u'閏十月': 110, u'閏十一月': 111, u'閏十二月': 112} '閏九月': 109, '閏十月': 110, '閏十一月': 111, '閏十二月': 112}
GAN = (u'', u'', u'', u'', u'', u'', u'', u'', u'', u'') GAN = ('', '', '', '', '', '', '', '', '', '')
ZHI = (u'', u'', u'', u'', u'', u'', ZHI = ('', '', '', '', '', '',
u'', u'', u'', u'', u'', u'') '', '', '', '', '', '')
SX = (u'', u'', u'', u'', u'', u'', SX = ('', '', '', '', '', '',
u'', u'', u'', u'', u'', u'') '', '', '', '', '', '')
def initdb(): def initdb():
try: try:
print 'creating db dir' print('creating db dir')
os.mkdir(os.path.join(APPDIR, 'db')) os.mkdir(os.path.join(APPDIR, 'db'))
except OSError: except OSError:
pass pass
@@ -101,7 +100,7 @@ def printjieqi():
res = query_db(sql) res = query_db(sql)
d = -75 d = -75
for row in res: for row in res:
print "%d: u'%s', " % (d, row[0]) print("%d: u'%s', " % (d, row[0]))
d += 15 d += 15
@@ -116,52 +115,17 @@ def query_db(query, args=(), one=False):
return (rv[0] if rv else None) if one else rv 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): def parse_hko(pageurl):
''' parse lunar calendar from hk Obs ''' parse lunar calendar from hk Obs
Args: pageurl Args: pageurl
Return: Return:
a string contains all posts''' a string contains all posts'''
print 'grabbing and parsing %s' % pageurl print('grabbing and parsing %s' % pageurl)
br = browser(PROXY) with urllib.request.urlopen(pageurl) as f:
lines = br.open(pageurl).readlines() html = f.read()
lines = html.decode('big5').split('\n')
sql_nojq = ('insert or replace into ical (date,lunardate) ' sql_nojq = ('insert or replace into ical (date,lunardate) '
'values(?,?) ') 'values(?,?) ')
sql_jq = ('insert or replace into ical (date,lunardate,jieqi) ' sql_jq = ('insert or replace into ical (date,lunardate,jieqi) '
@@ -169,7 +133,6 @@ def parse_hko(pageurl):
conn = sqlite3.connect(DB_FILE) conn = sqlite3.connect(DB_FILE)
db = conn.cursor() db = conn.cursor()
for line in lines: for line in lines:
line = line.decode('big5')
m = RE_CAL.match(line) m = RE_CAL.match(line)
if m: if m:
fds = line.split() fds = line.split()
@@ -193,7 +156,7 @@ def parse_hko(pageurl):
def update_cal(): def update_cal():
''' fetch lunar calendar from HongKong Obs, parse it and save to db''' ''' 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) parse_hko(URL % y)
@@ -209,15 +172,15 @@ def gen_cal(start, end, fp):
endyear = int(end[:4]) endyear = int(end[:4])
if startyear > 1900 and endyear < 2101: if startyear > 1900 and endyear < 2101:
# use Lunar Calendar from HKO # 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 ' sql = ('select date, lunardate, holiday, jieqi from ical '
'where date>=? and date<=? order by date') 'where date>=? and date<=? order by date')
rows = query_db(sql, (start, end)) rows = query_db(sql, (start, end))
else: else:
# compute Lunar Calendar by astronomical algorithm # compute Lunar Calendar by astronomical algorithm
print 'compute Lunar Calendar by astronomical algorithm ' print('compute Lunar Calendar by astronomical algorithm ')
rows = [] rows = []
for year in xrange(startyear, endyear + 1): for year in range(startyear, endyear + 1):
row = cn_lunarcal(year) row = cn_lunarcal(year)
rows.extend(row) rows.extend(row)
@@ -226,7 +189,7 @@ def gen_cal(start, end, fp):
for r in rows: for r in rows:
dt = datetime.strptime(r['date'], '%Y-%m-%d') 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'])] ld = ['%s%s' % (lunaryear(r['date']), r['lunardate'])]
else: else:
ld = [r['lunardate']] ld = [r['lunardate']]
@@ -239,12 +202,12 @@ def gen_cal(start, end, fp):
utcstamp = datetime.utcnow().strftime('%Y%m%dT%H%M%SZ') utcstamp = datetime.utcnow().strftime('%Y%m%dT%H%M%SZ')
line = ICAL_SEC % (utcstamp, uid, dt.strftime('%Y%m%d'), line = ICAL_SEC % (utcstamp, uid, dt.strftime('%Y%m%d'),
(dt + oneday).strftime('%Y%m%d'), summary) (dt + oneday).strftime('%Y%m%d'), summary)
lines.append(line.encode('utf8')) lines.append(line)
lines.append(ICAL_END) lines.append(ICAL_END)
outputf = open(fp, 'w') outputf = open(fp, 'w')
outputf.write('\n'.join(lines)) outputf.write('\n'.join(lines))
outputf.close() 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): def gen_cal_jieqi_only(start, end, fp):
@@ -259,23 +222,21 @@ def gen_cal_jieqi_only(start, end, fp):
endyear = int(end[:4]) endyear = int(end[:4])
if startyear > 1900 and endyear < 2101: if startyear > 1900 and endyear < 2101:
# use Lunar Calendar from HKO # 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 ' sql = ('select date, lunardate, holiday, jieqi from ical '
'where date>=? and date<=? order by date') 'where date>=? and date<=? order by date')
rows = query_db(sql, (start, end)) rows = query_db(sql, (start, end))
else: else:
# compute Lunar Calendar by astronomical algorithm # compute Lunar Calendar by astronomical algorithm
print 'compute Lunar Calendar by astronomical algorithm ' print('compute Lunar Calendar by astronomical algorithm ')
rows = [] rows = []
for year in xrange(startyear, endyear + 1): for year in range(startyear, endyear + 1):
row = cn_lunarcal(year) row = cn_lunarcal(year)
rows.extend(row) rows.extend(row)
lines = [ICAL_HEAD] lines = [ICAL_HEAD]
oneday = timedelta(days=1) oneday = timedelta(days=1)
for r in rows: for r in rows:
dt = datetime.strptime(r['date'], '%Y-%m-%d')
if not r['holiday'] and not r['jieqi']: if not r['holiday'] and not r['jieqi']:
continue continue
@@ -287,14 +248,15 @@ def gen_cal_jieqi_only(start, end, fp):
uid = '%s-lc@infinet.github.io' % r['date'] uid = '%s-lc@infinet.github.io' % r['date']
summary = ' '.join(ld) summary = ' '.join(ld)
utcstamp = datetime.utcnow().strftime('%Y%m%dT%H%M%SZ') 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'), line = ICAL_SEC % (utcstamp, uid, dt.strftime('%Y%m%d'),
(dt + oneday).strftime('%Y%m%d'), summary) (dt + oneday).strftime('%Y%m%d'), summary)
lines.append(line.encode('utf8')) lines.append(line)
lines.append(ICAL_END) lines.append(ICAL_END)
outputf = open(fp, 'w') outputf = open(fp, 'w')
outputf.write('\n'.join(lines)) outputf.write('\n'.join(lines))
outputf.close() 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(): def post_process():
@@ -308,8 +270,8 @@ def post_process():
conn = sqlite3.connect(DB_FILE) conn = sqlite3.connect(DB_FILE)
db = conn.cursor() db = conn.cursor()
for d in HK_ERROR: for d in HK_ERROR:
print 'fix lunar date for %s' % d print('fix lunar date for %s' % d)
db.execute(sql_update, (u'三十', d)) db.execute(sql_update, ('三十', d))
conn.commit() conn.commit()
@@ -339,27 +301,27 @@ def update_holiday():
continue continue
if m == 12 and d == 8: if m == 12 and d == 8:
args.append((r['id'], u'腊八')) args.append((r['id'], '腊八'))
elif m == 1 and d == 1: elif m == 1 and d == 1:
args.append((r['id'], u'春节')) args.append((r['id'], '春节'))
args.append((previd, u'除夕')) args.append((previd, '除夕'))
elif m == 1 and d == 15: elif m == 1 and d == 15:
args.append((r['id'], u'元宵')) args.append((r['id'], '元宵'))
elif m == 5 and d == 5: elif m == 5 and d == 5:
args.append((r['id'], u'端午')) args.append((r['id'], '端午'))
elif m == 7 and d == 7: elif m == 7 and d == 7:
args.append((r['id'], u'七夕')) args.append((r['id'], '七夕'))
elif m == 7 and d == 15: elif m == 7 and d == 15:
args.append((r['id'], u'中元')) args.append((r['id'], '中元'))
elif m == 8 and d == 15: elif m == 8 and d == 15:
args.append((r['id'], u'中秋')) args.append((r['id'], '中秋'))
elif m == 9 and d == 9: elif m == 9 and d == 9:
args.append((r['id'], u'重阳')) args.append((r['id'], '重阳'))
elif m == 10 and d == 15: elif m == 10 and d == 15:
args.append((r['id'], u'下元')) args.append((r['id'], '下元'))
if r['jieqi'] == u'清明': if r['jieqi'] == '清明':
args.append((previd, u'寒食')) args.append((previd, '寒食'))
previd = r['id'] previd = r['id']
sql_update = 'update ical set holiday=? where id=?' sql_update = 'update ical set holiday=? where id=?'
@@ -367,9 +329,9 @@ def update_holiday():
db = conn.cursor() db = conn.cursor()
for arg in args: for arg in args:
db.execute(sql_update, (arg[1], arg[0])) db.execute(sql_update, (arg[1], arg[0]))
print 'update %s' % arg[1] print('update %s' % arg[1])
conn.commit() conn.commit()
print 'Chinese Traditional Holiday updated' print('Chinese Traditional Holiday updated')
def ganzhi(lyear): def ganzhi(lyear):
@@ -383,7 +345,7 @@ def ganzhi(lyear):
g = GAN[int(str(lyear)[-1])] g = GAN[int(str(lyear)[-1])]
z = ZHI[int(lyear) % 12] z = ZHI[int(lyear) % 12]
sx = SX[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): def lunaryear(isodate):
@@ -415,8 +377,8 @@ def main():
opts, args = getopt.getopt(sys.argv[1:], 'h', opts, args = getopt.getopt(sys.argv[1:], 'h',
['start=', 'end=', 'help', 'jieqi']) ['start=', 'end=', 'help', 'jieqi'])
except getopt.GetoptError as err: except getopt.GetoptError as err:
print str(err) print(str(err))
print helpmsg print(helpmsg)
sys.exit(2) sys.exit(2)
jieqionly = False jieqionly = False
for o, v in opts: for o, v in opts:
@@ -460,7 +422,7 @@ def verify_lunarcalendar():
start = 1949 start = 1949
sql = 'select date, lunardate,jieqi from ical where date>=? and date<=?' sql = 'select date, lunardate,jieqi from ical where date>=? and date<=?'
while start < 2101: while start < 2101:
print 'compare %d' % start print('compare %d' % start)
ystart = '%d-01-01' % start ystart = '%d-01-01' % start
yend = '%d-12-31' % start yend = '%d-12-31' % start
res = query_db(sql, (ystart, yend)) res = query_db(sql, (ystart, yend))
@@ -472,15 +434,15 @@ def verify_lunarcalendar():
hko.append((x[0], x[1])) hko.append((x[0], x[1]))
aalc = cn_lunarcal(start) aalc = cn_lunarcal(start)
for i in xrange(len(aalc)): for i in range(len(aalc)):
aaday, aaldate = aalc[i]['date'], aalc[i]['lunardate'] aaday, aaldate = aalc[i]['date'], aalc[i]['lunardate']
if aalc[i]['jieqi']: if aalc[i]['jieqi']:
aaldate = '%s %s' % (aalc[i]['lunardate'], aalc[i]['jieqi']) aaldate = '%s %s' % (aalc[i]['lunardate'], aalc[i]['jieqi'])
hkoday, hkoldate = hko[i] hkoday, hkoldate = hko[i]
#print aaday, aaldate #print aaday, aaldate
if aaday != hkoday or aaldate != hkoldate: if aaday != hkoday or aaldate != hkoldate:
print 'AA %s %s, HKO %s %s' % (aaday, aaldate, hkoday, print('AA %s %s, HKO %s %s' % (aaday, aaldate, hkoday,
hkoldate) hkoldate))
start += 1 start += 1

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python #!/usr/bin/env python3
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
''' generate Chinese Lunar Calendar by astronomical algorithms. Also mark the ''' generate Chinese Lunar Calendar by astronomical algorithms. Also mark the
@@ -17,42 +17,42 @@ __all__ = ['cn_lunarcal']
LCSTARTMONTH = 11 LCSTARTMONTH = 11
CN_DAY = {2: u'初二', 3: u'初三', 4: u'初四', 5: u'初五', 6: u'初六', CN_DAY = {2: '初二', 3: '初三', 4: '初四', 5: '初五', 6: '初六',
7: u'初七', 8: u'初八', 9: u'初九', 10: u'初十', 11: u'十一', 7: '初七', 8: '初八', 9: '初九', 10: '初十', 11: '十一',
12: u'十二', 13: u'十三', 14: u'十四', 15: u'十五', 16: u'十六', 12: '十二', 13: '十三', 14: '十四', 15: '十五', 16: '十六',
17: u'十七', 18: u'十八', 19: u'十九', 20: u'二十', 21: u'廿一', 17: '十七', 18: '十八', 19: '十九', 20: '二十', 21: '廿一',
22: u'廿二', 23: u'廿三', 24: u'廿四', 25: u'廿五', 26: u'廿六', 22: '廿二', 23: '廿三', 24: '廿四', 25: '廿五', 26: '廿六',
27: u'廿七', 28: u'廿八', 29: u'廿九', 30: u'三十'} 27: '廿七', 28: '廿八', 29: '廿九', 30: '三十'}
CN_MON = {1: u'正月', 2: u'二月', 3: u'三月', 4: u'四月', CN_MON = {1: '正月', 2: '二月', 3: '三月', 4: '四月',
5: u'五月', 6: u'六月', 7: u'七月', 8: u'八月', 5: '五月', 6: '六月', 7: '七月', 8: '八月',
9: u'九月', 10: u'十月', 11: u'十一月', 12: u'十二月', 9: '九月', 10: '十月', 11: '十一月', 12: '十二月',
99: u'閏十一月', 100: u'閏十二月', 101: u'閏正月', 99: '閏十一月', 100: '閏十二月', 101: '閏正月',
102: u'閏二月', 103: u'閏三月', 104: u'閏四月', 102: '閏二月', 103: '閏三月', 104: '閏四月',
105: u'閏五月', 106: u'閏六月', 107: u'閏七月', 105: '閏五月', 106: '閏六月', 107: '閏七月',
108: u'閏八月', 109: u'閏九月', 110: u'閏十月', 108: '閏八月', 109: '閏九月', 110: '閏十月',
111: u'閏十一月', 112: u'閏十二月'} 111: '閏十一月', 112: '閏十二月'}
CN_SOLARTERM = {-120: u'小雪',-105: u'大雪', CN_SOLARTERM = {-120: '小雪',-105: '大雪',
-90: u'冬至', -75: u'小寒', -60: u'大寒', -90: '冬至', -75: '小寒', -60: '大寒',
-45: u'立春', -30: u'雨水', -15: u'惊蛰', -45: '立春', -30: '雨水', -15: '惊蛰',
0: u'春分', 15: u'清明', 30: u'谷雨', 0: '春分', 15: '清明', 30: '谷雨',
45: u'立夏', 60: u'小满', 75: u'芒种', 45: '立夏', 60: '小满', 75: '芒种',
90: u'夏至', 105: u'小暑', 120: u'大暑', 90: '夏至', 105: '小暑', 120: '大暑',
135: u'立秋', 150: u'处暑', 165: u'白露', 135: '立秋', 150: '处暑', 165: '白露',
180: u'秋分', 195: u'寒露', 210: u'霜降', 180: '秋分', 195: '寒露', 210: '霜降',
225: u'立冬', 240: u'小雪', 255: u'大雪', 270: u'冬至'} 225: '立冬', 240: '小雪', 255: '大雪', 270: '冬至'}
CN_SOLARTERM = {-120: u'小雪',-105: u'大雪', CN_SOLARTERM = {-120: '小雪',-105: '大雪',
-90: u'冬至', -75: u'小寒', -60: u'大寒', -90: '冬至', -75: '小寒', -60: '大寒',
-45: u'立春', -30: u'雨水', -15: u'驚蟄', -45: '立春', -30: '雨水', -15: '驚蟄',
0: u'春分', 15: u'清明', 30: u'穀雨', 0: '春分', 15: '清明', 30: '穀雨',
45: u'立夏', 60: u'小滿', 75: u'芒種', 45: '立夏', 60: '小滿', 75: '芒種',
90: u'夏至', 105: u'小暑', 120: u'大暑', 90: '夏至', 105: '小暑', 120: '大暑',
135: u'立秋', 150: u'處暑', 165: u'白露', 135: '立秋', 150: '處暑', 165: '白露',
180: u'秋分', 195: u'寒露', 210: u'霜降', 180: '秋分', 195: '寒露', 210: '霜降',
225: u'立冬', 240: u'小雪', 255: u'大雪', 270: u'冬至'} 225: '立冬', 240: '小雪', 255: '大雪', 270: '冬至'}
# calendar for this and next year are combined to generate the final output # calendar for this and next year are combined to generate the final output
@@ -90,9 +90,9 @@ def find_astro(year):
aadays.sort() aadays.sort()
# normalize all Julian Day to midnight for later compare # 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] 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 return astro
@@ -118,7 +118,7 @@ def mark_lunarcal_month(clc):
# mark month name, 11 is the month contains Winter Solstice # mark month name, 11 is the month contains Winter Solstice
newmoondate = [d['date'] for d in clc if d['astro'] == 'newmoon'] newmoondate = [d['date'] for d in clc if d['astro'] == 'newmoon']
mname = 11 mname = 11
for i in xrange(len(newmoondate) - 1): for i in range(len(newmoondate) - 1):
thisnm, nextnm = newmoondate[i], newmoondate[i + 1] thisnm, nextnm = newmoondate[i], newmoondate[i + 1]
if thisnm < lcstart: if thisnm < lcstart:
continue continue
@@ -155,7 +155,7 @@ def scan_leap(clc):
# leap year has more than 12 newmoons between two Winter Solstice # leap year has more than 12 newmoons between two Winter Solstice
if nmcount > 12: if nmcount > 12:
# search leap month from LC 11, to next LC 11, which = 11 + 13 # 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 foundleap = True
for d in clc: for d in clc:
if d['astro'] == 'newmoon': 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'] m, d = clcdays[i]['month'], clcdays[i]['day']
if m == 12 and d == 8: if m == 12 and d == 8:
clcdays[i]['holiday'] = u'腊八' clcdays[i]['holiday'] = '腊八'
elif m == 1 and d == 1: elif m == 1 and d == 1:
clcdays[i]['holiday'] = u'春节' clcdays[i]['holiday'] = '春节'
clcdays[i - 1]['holiday'] = u'除夕' clcdays[i - 1]['holiday'] = '除夕'
elif m == 1 and d == 15: elif m == 1 and d == 15:
clcdays[i]['holiday'] = u'元宵' clcdays[i]['holiday'] = '元宵'
elif m == 5 and d == 5: elif m == 5 and d == 5:
clcdays[i]['holiday'] = u'端午' clcdays[i]['holiday'] = '端午'
elif m == 7 and d == 7: elif m == 7 and d == 7:
clcdays[i]['holiday'] = u'七夕' clcdays[i]['holiday'] = '七夕'
elif m == 7 and d == 15: elif m == 7 and d == 15:
clcdays[i]['holiday'] = u'中元' clcdays[i]['holiday'] = '中元'
elif m == 8 and d == 15: elif m == 8 and d == 15:
clcdays[i]['holiday'] = u'中秋' clcdays[i]['holiday'] = '中秋'
elif m == 9 and d == 9: elif m == 9 and d == 9:
clcdays[i]['holiday'] = u'重阳' clcdays[i]['holiday'] = '重阳'
elif m == 10 and d == 15: elif m == 10 and d == 15:
clcdays[i]['holiday'] = u'下元' clcdays[i]['holiday'] = '下元'
if clcdays[i]['jieqi'] == u'清明': if clcdays[i]['jieqi'] == '清明':
clcdays[i - 1]['holiday'] = u'寒食' clcdays[i - 1]['holiday'] = '寒食'
return clcdays return clcdays
@@ -302,13 +302,13 @@ def cn_lunarcal(year):
cal0 = search_lunarcal(year) cal0 = search_lunarcal(year)
cal1 = search_lunarcal(year + 1) cal1 = search_lunarcal(year + 1)
for k, v in cal1.iteritems(): for k, v in cal1.items():
cal0[k] = v cal0[k] = v
start = jdptime('%s-%s-%s' % (year, 1, 1), '%y-%m-%d') start = jdptime('%s-%s-%s' % (year, 1, 1), '%y-%m-%d')
end = jdptime('%s-%s-%s' % (year, 12, 31), '%y-%m-%d') end = jdptime('%s-%s-%s' % (year, 12, 31), '%y-%m-%d')
lc = [] lc = []
for jd, day in cal0.iteritems(): for jd, day in cal0.items():
day['date'] = jdftime(jd, '%y-%m-%d', ut=False) day['date'] = jdftime(jd, '%y-%m-%d', ut=False)
if jd >= start and jd <= end: if jd >= start and jd <= end:
lc.append((jd, day)) lc.append((jd, day))
@@ -322,7 +322,7 @@ def cn_lunarcal(year):
def main(): def main():
a = cn_lunarcal(2033) a = cn_lunarcal(2033)
for x in a: 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__": if __name__ == "__main__":