This article mainly introduces the method of realizing the Gregorian calendar (lunar calendar), which involves the Chinese lunar algorithm principle and the Python date arithmetic related operation skills, the need of friends can refer to the following
The example in this paper describes how Python implements the Gregorian calendar (lunar calendar) to the lunar calendar. Share to everyone for your reference, as follows:
Two points:
1, the Gregorian calendar to the lunar calendar using the table method (line 126th)
2, the solar terms used astronomical method? (Line 176th)
Run Graph (background is hao123 calendar)
Source:
# lunar.py# 2015/02/27 Luo Bing import datetimeclass Lunar (object): #****************************************************** # below for the lunar calendar to calculate the required data, in order to save storage space, so use the following more abnormal storage methods. #****************************************************************************** #数组g_lunar_month_ Day is deposited on the lunar calendar from 1901 to 2050 each year, #阴历每月只能是29或30天, 12 (or 13) bits a year, the corresponding bit is 1 table 30 days, otherwise 29 days g_lunar_month_day = [0x4ae0, 0xa570, 0x5268, 0xd260, 0xd950, 0x6aa8, 0x56a0, 0x9ad0, 0x4ae8, 0x4ae0, #1910 0xa4d8, 0xa4d0, 0xd250, 0xd548, 0xb550, 0x56a0, 0x96d0, 0x95b0, 0x49b8, 0x49b0, #1920 0xa4b0, 0xb258, 0x6a50, 0X6D40, 0xada8, 0x2b60, 0x9570, 0x4978, 0x4970, 0x64b0, #1930 0xd4a0, 0xea50, 0x6d48, 0x5ad0, 0x2b60, 0x9370, 0x92e0, 0xc968, 0xc950, 0xd4a0, #1940 0xda50, 0xb550, 0x56a 0, 0xaad8, 0x25d0, 0x92d0, 0xc958, 0xa950, 0xb4a8, 0x6ca0, #1950 0xb550, 0x55a8, 0x4da0, 0xa5b0, 0x52b8, 0x52b0, 0xa95 0, 0xe950, 0x6aa0, 0XAD50, #1960 0xab50, 0x4b60, 0xa570, 0xa570, 0x5260, 0xe930, 0xd950, 0x5aa8, 0x56a0,0x96d0, #1970 0x4ae8, 0x4ad0, 0xa4d0, 0xd268, 0xd250, 0xd528, 0xb540, 0xb6a0, 0x96d0, 0x95b0, #1980 0x49b0, 0xa4b8 , 0xa4b0, 0xb258, 0x6a50, 0X6D40, 0xada0, 0xab60, 0x9370, 0x4978, #1990 0x4970, 0x64b0, 0x6a50, 0xea50, 0x6b28, 0x5ac0 , 0xab60, 0x9368, 0x92e0, 0xc960, #2000 0xd4a8, 0xd4a0, 0xda50, 0x5aa8, 0x56a0, 0xaad8, 0x25d0, 0x92d0, 0xc958, 0xa950 , #2010 0xb4a0, 0xb550, 0xb550, 0x55a8, 0x4ba0, 0xa5b0, 0x52b8, 0x52b0, 0xa930, 0x74a8, #2020 0x6aa0, 0XAD50, 0x4d A8, 0x4b60, 0x9570, 0xa4e0, 0xd260, 0xe930, 0xd530, 0x5aa0, #2030 0x6b50, 0x96d0, 0x4ae8, 0x4ad0, 0xa4d0, 0xd258, 0xd2 0xd520, 0xdaa0, 0xb5a0, #2040 0x56d0, 0x4ad8, 0x49b0, 0xa4b8, 0xa4b0, 0xaa50, 0xb528, 0X6D20, 0xada0, 0x55b0, #20 #数组gLanarMonth存放阴历1901年到2050年闰月的月份, if not, 0 per byte for two years g_lunar_month = [0x00, 0x50, 0x04, 0x00, 0x20, #1910 0x60 , 0x05, 0x00, 0x20, 0x70, #1920 0x05, 0x00, 0x40, 0x02, 0x06, #1930 0x00, 0x50, 0x03, 0x07, 0x00, #1940 0x60, 0x04, 0x00, 0x20, 0x70, #1950 0x05, 0x00, 0x30, 0x80, 0x06, #1960 0x00, 0x40, 0x03, 0x07, 0x00, #1970 0x50, 0x04, 0x08, 0x00, 0x60, # 1980 0x04, 0x0a, 0x00, 0x60, 0x05, #1990 0x00, 0x30, 0x80, 0x05, 0x00, #2000 0x40, 0x02, 0x07, 0x00, 0x50, #20 Ten 0x04, 0x09, 0x00, 0x60, 0x04, #2020 0x00, 0x20, 0x60, 0x05, 0x00, #2030 0x30, 0xb0, 0x06, 0x00, 0x50, #2040 0x02, 0x07, 0x00, 0x50, 0x03 #2050] start_year = 1901 # Zodiac Gan = ' methyl-propyl-n-heptyl Xing ' # earthly zhi = ' obscure Chen Wu Shin ' # zodiac Xiao = ' Rat cow tiger rabbit dragon snake horse sheep monkey Chicken Dog pig ' # month LM = ' 234,567,890 winter wax ' # Japanese ld = ' first day second day third day four Duanwu arrest When初七because holidays Penggushan 1.,234,567,892,212,22e,+28 Ten ' # Jie = ' Xiaohan Big chill spring Rain jingzhe vernal equinox Ching Ming gu Xiantane kinds of summer solstice slight heat great heat autumn Chushu Belutiu points dew frost winter snow Winter Solstice ' Def __init__ (self, dt = None): "' Initialization: parameter is DATETIME.D Atetime class instance, default current time ' self.localtime = dt if dt else Datetime.datetime.today () def sx_year (self): # return zodiac Year ct = self. LocalTime #取当前时间 year = self.ln_year ()-3-1 # 3 (Note: 1) years = 12 # modulo 12, get the number of branches return Self.xiao[ye AR] def gz_year (self):# return Ganzhi Annals ct = self.localtime #取当前时间 year = self.ln_year ()-3-1 # 3 (Note: 1) G = years% 10 # modulo 10, get zodiac number Z = year% 12 # modulo 12, get the number of branches return SELF.GAN[G] + self.zhi[z] def gz_month (self): # return Ganzhi Guile (not implemented) pass Def Gz_day : # return Ganzhi ct = self.localtime #取当前时间 C = ct.year//#取世纪数, minus one y = ct.year% #取年份后两位 (if January, February the current year minus one) y = Y-1 if Ct.month = = 1 or Ct.month = = 2 Else y M = Ct.month #取月份 (if January, February respectively by 13, 14来) m = m + if Ct.month = = 1 or Ct.month = = 2 else M d = ct.day #取日数 i = 0 if ct.month% 2 = = 1 Else 6 #取i (odd month i=0, even months i=6) #下面两个是网上的公式 # HT Tp://baike.baidu.com/link?url= MBTKMHRTHTOAZ735GI37TETWD29ZQE9GJ92CZQZD0X8UFO5XGMYMKQRU6AETZCGADQEKZKD3NZHVS99REWYA6Q # Calculation Dry (note: 1) G = 4 * C + C/ /4 + 5 * y + Y//4 + 3 * (M + 1)//5 + d-3-1 G = G% 10 # calculation support (description: minus 1) Z = 8 * C + C//4 + 5 * y + y//4 + 3 * (M + 1)//5 + D + 7 + i-1 z = z% #返回 Ganzhi day return self.gan[g] + self.zhi[z] def gz_hour (self): # return Ganzhi (hour) ct = self.localtime #取当前时间 #计算支 Z = Round ((CT.HOUR/2) + 0.1)% 12 # The reason for adding 0.1 is because round bug!! #返回 Ganzhi (hour) return self.zhi[z] def ln_year (self): # return lunar Year, _, _ = Self.ln_date () return years def Ln_month (self): # return lunar month _, month, _ = Self.ln_date () return month def ln_day (self): # Return to Lunar Calendar _, _, day = Self.ln_date () Return Day def ln_date (self): # Returns the lunar calendar integer tuple (year, month, day) (table method) Delta_days = Self._date_diff () #阳历1901年2月19日为阴历1901年正月初一 #阳历1901年1月1日到2月19日共有49天 if (Delta_days <): Year = self. Start_year-1 if (delta_days <19): month = 11; Day = one + delta_days else:month = 12; Day = delta_days-18 return (year, month, day) #下面从阴历1901年正月初一算起 delta_days-=, month, day = Self.s Tart_year, 1, 1 #计算年 tmp = self._lunar_year_days (year) while delta_days >= tmp:delta_days-= tmp ye AR + = 1 tmp = self._lunar_year_days (year) #计算月 (foo, tmp) = self._lunar_month_days (year, month) while delta_days >= tmp:delta_days = tmp if (month = = Self._get_leap_mont H (year)): (tmp, foo) = Self._lunar_month_days (year, month) if (Delta_days < TMP): return (0, 0, 0) return (year, month, delta_days+1) delta_days-= tmp month + = 1 (foo, tmp) = Self._lunar_mont H_days (year, month) #计算日 Day + = Delta_days return (year, month, day) def ln_date_str (self): # Returns the lunar date string, as follows: The lunar month is nine _, month, day = Self.ln_date () return ' Lunar {} month {} '. Format (self.lm[month-1], self.ld[(day-1) *2:day*2]) def Ln_jie (self ): # Return lunar solar term ct = self.localtime #取当前时间 year = Ct.year for I in range: #因为两个都是浮点数, delta = SE cannot be represented by equality Lf._julian_day ()-Self._julian_day_of_ln_jie (year, i) if-.5 <= Delta <=. 5:return self.jie[i*2: (i+1) * 2] return ' #显示日历 def calendar (self): Pass ####################################################### # below are private There is a function ####################################################### def _date_diff (self): "returned based on 1901/01/01 day difference" return (Self.localtime-datetim E.datetime (1901, 1, 1)). Days def _get_leap_month (self, lunar_year): Flag = self.g_lunar_month[(lunar_year-self. Start_year)//2] if (lunar_year-self. Start_year)% 2:return flag & 0x0f Else:return flag >> 4 def _lunar_month_days (self, lunar_year, Lunar_month): if (Lunar_year < self. Start_year): return, low = 0, ibit = 16-lunar_month; if (Lunar_month > Self._get_leap_month (lunar_year) and Self._get_leap_month (lunar_year)): ibit-= 1 if (self.g_ Lunar_month_day[lunar_year-self. Start_year] & (1 << ibit)): Low + = 1 if (Lunar_month = = Self._get_leap_month (lunar_year)): if (self . g_lunar_month_day[lunar_year-self. Start_year] & (1 << (iBit-1)): High = Else:high = return (high, low) def _luna R_year_days (self, year): Days = 0 For I in range (1, +) = Self._lunar_month_days (year, i) days + = high days + = low return Days # Returns the Julian day of the specified Gregorian date def _julian_day (self): ct = self.localtime #取当前时间 year = ct.year month = Ct.month Day = Ct.day If month <= 2:month + + year-to-1 B = year/100 B = 2-b + year/400 DD = day + 0.5 000115740 #本日12:00 is the beginning of the Julian Day (after one second) */return int (365.25 * (year + 4716) + 0.01) + int (30.60001 * (month + 1)) + DD + B- 1524.5 # Returns the number of days of the solar term for the specified year Def _julian_day_of_ln_jie (self, Year, ST): S_staccinfo =[0.00, 1272494.40, 2548020.60, 3830143.80, 5120226.60, 6420865.80, 7732018.80, 9055272.60, 10388958.00, 11733065.40, 13084292.40, 14441592.00, 15800560.80, 17159347.20, 18513766.20, 19862002.20, 21201005.40, 22529659.80, 23846845.20, 25152606.00, 26447687. 27733451.40, 29011921.20, 30285477.60] #已知1900年小寒时刻为1月6日02:05:00 BASE1900_SLIGHTCOLDJD = 2415025.5868055555 I F (St < 0) or (St; ): return 0.0 STJD = 365.24219878 * (year-1900) + s_staccinfo[st]/86400.0 return BASE1900_SLIGHTCOLDJD + stjd# Testing def Test (ct=none): ln = Lunar (CT) print (' Gregorian {} GMT {} '. Format (Ln.localtime.date (), Ln.localtime.time ())) print (' {} ' {} ' {} ' {} {} days {} '. Format (Ln.ln_date_str (), Ln.gz_year (), Ln.sx_year (), Ln.gz_day (), Ln.gz_hour ()) "Print (' throttle: {} '). Format (Ln.ln_jie ())) if __name__ = = ' __main__ ': ct = datetime.datetime (2015,2,19,13,0,15) test (CT)