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以加快计算速度。
|
* [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
130
aa.py
@@ -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__":
|
||||||
|
|||||||
19
aa_full.py
19
aa_full.py
@@ -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
|
||||||
|
|||||||
166
lunar_ical.py
166
lunar_ical.py
@@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
106
lunarcalbase.py
106
lunarcalbase.py
@@ -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__":
|
||||||
|
|||||||
Reference in New Issue
Block a user