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