python多线程实现_Python实现公历(阳历)转农历(阴历)的方法示例

时间:2021-08-11  来源:python  阅读:

两个要点:

1、公历转农历用了查表法(第126行)

2、节气用了天文法?(第176行)

运行图(背景是hao123万年历)

源代码:

# lunar.py
# 2015/02/27 罗兵
importdatetime
classLunar(object):
  #******************************************************************************
  # 下面为阴历计算所需的数据,为节省存储空间,所以采用下面比较变态的存储方法.
  #******************************************************************************
  #数组g_lunar_month_day存入阴历1901年到2050年每年中的月天数信息,
  #阴历每月只能是29或30天,一年用12(或13)个二进制位表示,对应位为1表30天,否则为29天
  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,0x56a0,0xaad8,0x25d0,0x92d0,0xc958,0xa950,0xb4a8,0x6ca0, #1950
    0xb550,0x55a8,0x4da0,0xa5b0,0x52b8,0x52b0,0xa950,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,0x4da8,0x4b60,0x9570,0xa4e0,0xd260,0xe930,0xd530,0x5aa0, #2030
    0x6b50,0x96d0,0x4ae8,0x4ad0,0xa4d0,0xd258,0xd250,0xd520,0xdaa0,0xb5a0, #2040
    0x56d0,0x4ad8,0x49b0,0xa4b8,0xa4b0,0xaa50,0xb528,0x6d20,0xada0,0x55b0, #2050
  ]
  #数组gLanarMonth存放阴历1901年到2050年闰月的月份,如没有则为0,每字节存两年
  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, #2010
    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
  # 天干
  gan="甲乙丙丁戊己庚辛壬癸"
  # 地支
  zhi="子丑寅卯辰巳午未申酉戌亥"
  # 生肖
  xiao="鼠牛虎兔龙蛇马羊猴鸡狗猪"
  # 月份
  lm="正二三四五六七八九十冬腊"
  # 日份
  ld="初一初二初三初四初五初六初七初八初九初十十一十二十三十四十五十六十七十八十九二十廿一廿二廿三廿四廿五廿六廿七廿八廿九三十"
  # 节气
  jie="小寒大寒立春雨水惊蛰春分清明谷雨立夏小满芒种夏至小暑大暑立秋处暑白露秋分寒露霜降立冬小雪大雪冬至"
  def__init__(self, dt=None):
    """初始化:参数为datetime.datetime类实例,默认当前时间"""
    self.localtime=dtifdtelsedatetime.datetime.today()
  defsx_year(self):# 返回生肖年
    ct=self.localtime#取当前时间
    year=self.ln_year()-3-1# 农历年份减3 (说明:补减1)
    year=year%12# 模12,得到地支数
    returnself.xiao[year]
  defgz_year(self):# 返回干支纪年
    ct=self.localtime#取当前时间
    year=self.ln_year()-3-1# 农历年份减3 (说明:补减1)
    G=year%10# 模10,得到天干数
    Z=year%12# 模12,得到地支数
    returnself.gan[G]+self.zhi[Z]
  defgz_month(self):# 返回干支纪月(未实现)
    pass
  defgz_day(self):# 返回干支纪日
    ct=self.localtime#取当前时间
    C=ct.year//100#取世纪数,减一
    y=ct.year%100#取年份后两位(若为1月、2月则当前年份减一)
    y=y-1ifct.month==1orct.month==2elsey
    M=ct.month#取月份(若为1月、2月则分别按13、14来计算)
    M=M+12ifct.month==1orct.month==2elseM
    d=ct.day#取日数
    i=0ifct.month%2==1else6#取i (奇数月i=0,偶数月i=6)
    #下面两个是网上的公式
    # http://baike.baidu.com/link?url=MbTKmhrTHTOAz735gi37tEtwd29zqE9GJ92cZQZd0X8uFO5XgmyMKQru6aetzcGadqekzKd3nZHVS99rewya6q
    # 计算干(说明:补减1)
    G=4*C+C//4+5*y+y//4+3*(M+1)//5+d-3-1
    G=G%10
    # 计算支(说明:补减1)
    Z=8*C+C//4+5*y+y//4+3*(M+1)//5+d+7+i-1
    Z=Z%12
    #返回 干支纪日
    returnself.gan[G]+self.zhi[Z]
  defgz_hour(self):# 返回干支纪时(时辰)
    ct=self.localtime#取当前时间
    #计算支
    Z=round((ct.hour/2)+0.1)%12# 之所以加0.1是因为round的bug!!
    #返回 干支纪时(时辰)
    returnself.zhi[Z]
  defln_year(self):# 返回农历年
    year, _, _=self.ln_date()
    returnyear
  defln_month(self):# 返回农历月
    _, month, _=self.ln_date()
    returnmonth
  defln_day(self):# 返回农历日
    _, _, day=self.ln_date()
    returnday
  defln_date(self):# 返回农历日期整数元组(年、月、日)(查表法)
    delta_days=self._date_diff()
    #阳历1901年2月19日为阴历1901年正月初一
    #阳历1901年1月1日到2月19日共有49天
    if(delta_days <49):
      year=self.START_YEAR-1
      if(delta_days <19):
       month=11;
       day=11+delta_days
      else:
        month=12;
        day=delta_days-18
      return(year, month, day)
    #下面从阴历1901年正月初一算起
    delta_days-=49
    year, month, day=self.START_YEAR,1,1
    #计算年
    tmp=self._lunar_year_days(year)
    whiledelta_days >=tmp:
      delta_days-=tmp
      year+=1
      tmp=self._lunar_year_days(year)
    #计算月
    (foo, tmp)=self._lunar_month_days(year, month)
    whiledelta_days >=tmp:
      delta_days-=tmp
      if(month==self._get_leap_month(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_month_days(year, month)
    #计算日
    day+=delta_days
    return(year, month, day)
  defln_date_str(self):# 返回农历日期字符串,形如:农历正月初九
    _, month, day=self.ln_date()
    return"农历{}月{}".format(self.lm[month-1],self.ld[(day-1)*2:day*2])
  defln_jie(self):# 返回农历节气
    ct=self.localtime#取当前时间
    year=ct.year
    foriinrange(24):
      #因为两个都是浮点数,不能用相等表示
      delta=self._julian_day()-self._julian_day_of_ln_jie(year, i)
      if-.5<=delta <=.5:
        returnself.jie[i*2:(i+1)*2]
    return""
  #显示日历
  defcalendar(self):
    pass
  #######################################################
  #      下面皆为私有函数
  #######################################################
  def_date_diff(self):
    """返回基于1901/01/01日差数"""
    return(self.localtime-datetime.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:
      returnflag &0x0f
    else:
      returnflag >>4
  def_lunar_month_days(self, lunar_year, lunar_month):
    if(lunar_year self._get_leap_month(lunar_year)andself._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=30
      else:
         high=29
    return(high, low)
  def_lunar_year_days(self, year):
    days=0
    foriinrange(1,13):
      (high, low)=self._lunar_month_days(year, i)
      days+=high
      days+=low
    returndays
  # 返回指定公历日期的儒略日
  def_julian_day(self):
    ct=self.localtime#取当前时间
    year=ct.year
    month=ct.month
    day=ct.day
    ifmonth <=2:
      month+=12
      year-=1
    B=year/100
    B=2-B+year/400
    dd=day+0.5000115740#本日12:00后才是儒略日的开始(过一秒钟)*/
    returnint(365.25*(year+4716)+0.01)+int(30.60001*(month+1))+dd+B-1524.5
  # 返回指定年份的节气的儒略日数
  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.40,27733451.40,29011921.20,30285477.60]
    #已知1900年小寒时刻为1月6日02:05:00
    base1900_SlightColdJD=2415025.5868055555
    if(st <0)or(st >24):
      return0.0
    stJd=365.24219878*(year-1900)+s_stAccInfo[st]/86400.0
    returnbase1900_SlightColdJD+stJd
# 测试
deftest(ct=None):
  ln=Lunar(ct)
  print("公历 {} 北京时间 {}".format(ln.localtime.date(), ln.localtime.time()))
  print("{} 【{}】 {}年 {}日 {}时".format(ln.ln_date_str(), ln.gz_year(), ln.sx_year(), ln.gz_day(), ln.gz_hour()))
  print("节气:{}".format(ln.ln_jie()))
if__name__=="__main__":
  ct=datetime.datetime(2015,2,19,13,0,15)
  test(ct)

python多线程实现_Python实现公历(阳历)转农历(阴历)的方法示例

http://m.bbyears.com/jiaocheng/135361.html

推荐访问:python实现des python单例模式实现
相关阅读 猜你喜欢
本类排行 本类最新