大杂烩。作为自己的记录,保存。

两个要点

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

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

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

源代码

 # lunar.py
# 2015/02/27 罗兵
import datetime class Lunar(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, #
0xa4d8, 0xa4d0, 0xd250, 0xd548, 0xb550, 0x56a0, 0x96d0, 0x95b0, 0x49b8, 0x49b0, #
0xa4b0, 0xb258, 0x6a50, 0x6d40, 0xada8, 0x2b60, 0x9570, 0x4978, 0x4970, 0x64b0, #
0xd4a0, 0xea50, 0x6d48, 0x5ad0, 0x2b60, 0x9370, 0x92e0, 0xc968, 0xc950, 0xd4a0, #
0xda50, 0xb550, 0x56a0, 0xaad8, 0x25d0, 0x92d0, 0xc958, 0xa950, 0xb4a8, 0x6ca0, #
0xb550, 0x55a8, 0x4da0, 0xa5b0, 0x52b8, 0x52b0, 0xa950, 0xe950, 0x6aa0, 0xad50, #
0xab50, 0x4b60, 0xa570, 0xa570, 0x5260, 0xe930, 0xd950, 0x5aa8, 0x56a0, 0x96d0, #
0x4ae8, 0x4ad0, 0xa4d0, 0xd268, 0xd250, 0xd528, 0xb540, 0xb6a0, 0x96d0, 0x95b0, #
0x49b0, 0xa4b8, 0xa4b0, 0xb258, 0x6a50, 0x6d40, 0xada0, 0xab60, 0x9370, 0x4978, #
0x4970, 0x64b0, 0x6a50, 0xea50, 0x6b28, 0x5ac0, 0xab60, 0x9368, 0x92e0, 0xc960, #
0xd4a8, 0xd4a0, 0xda50, 0x5aa8, 0x56a0, 0xaad8, 0x25d0, 0x92d0, 0xc958, 0xa950, #
0xb4a0, 0xb550, 0xb550, 0x55a8, 0x4ba0, 0xa5b0, 0x52b8, 0x52b0, 0xa930, 0x74a8, #
0x6aa0, 0xad50, 0x4da8, 0x4b60, 0x9570, 0xa4e0, 0xd260, 0xe930, 0xd530, 0x5aa0, #
0x6b50, 0x96d0, 0x4ae8, 0x4ad0, 0xa4d0, 0xd258, 0xd250, 0xd520, 0xdaa0, 0xb5a0, #
0x56d0, 0x4ad8, 0x49b0, 0xa4b8, 0xa4b0, 0xaa50, 0xb528, 0x6d20, 0xada0, 0x55b0, #
] #数组gLanarMonth存放阴历1901年到2050年闰月的月份,如没有则为0,每字节存两年
g_lunar_month = [
0x00, 0x50, 0x04, 0x00, 0x20, #
0x60, 0x05, 0x00, 0x20, 0x70, #
0x05, 0x00, 0x40, 0x02, 0x06, #
0x00, 0x50, 0x03, 0x07, 0x00, #
0x60, 0x04, 0x00, 0x20, 0x70, #
0x05, 0x00, 0x30, 0x80, 0x06, #
0x00, 0x40, 0x03, 0x07, 0x00, #
0x50, 0x04, 0x08, 0x00, 0x60, #
0x04, 0x0a, 0x00, 0x60, 0x05, #
0x00, 0x30, 0x80, 0x05, 0x00, #
0x40, 0x02, 0x07, 0x00, 0x50, #
0x04, 0x09, 0x00, 0x60, 0x04, #
0x00, 0x20, 0x60, 0x05, 0x00, #
0x30, 0xb0, 0x06, 0x00, 0x50, #
0x02, 0x07, 0x00, 0x50, 0x03 #
] START_YEAR = 1901 # 天干
gan = '甲乙丙丁戊己庚辛壬癸'
# 地支
zhi = '子丑寅卯辰巳午未申酉戌亥'
# 生肖
xiao = '鼠牛虎兔龙蛇马羊猴鸡狗猪'
# 月份
lm = '正二三四五六七八九十冬腊'
# 日份
ld = '初一初二初三初四初五初六初七初八初九初十十一十二十三十四十五十六十七十八十九二十廿一廿二廿三廿四廿五廿六廿七廿八廿九三十'
# 节气
jie = '小寒大寒立春雨水惊蛰春分清明谷雨立夏小满芒种夏至小暑大暑立秋处暑白露秋分寒露霜降立冬小雪大雪冬至' def __init__(self, dt = None):
'''初始化:参数为datetime.datetime类实例,默认当前时间'''
self.localtime = dt if dt else datetime.datetime.today() def sx_year(self): # 返回生肖年
ct = self.localtime #取当前时间 year = self.ln_year() - 3 - 1 # 农历年份减3 (说明:补减1)
year = year % 12 # 模12,得到地支数
return self.xiao[year] def gz_year(self): # 返回干支纪年
ct = self.localtime #取当前时间
year = self.ln_year() - 3 - 1 # 农历年份减3 (说明:补减1)
G = year % 10 # 模10,得到天干数
Z = year % 12 # 模12,得到地支数
return self.gan[G] + self.zhi[Z] def gz_month(self): # 返回干支纪月(未实现)
pass def gz_day(self): # 返回干支纪日
ct = self.localtime #取当前时间
C = ct.year // 100 #取世纪数,减一
y = ct.year % 100 #取年份后两位(若为1月、2月则当前年份减一)
y = y - 1 if ct.month == 1 or ct.month == 2 else y
M = ct.month #取月份(若为1月、2月则分别按13、14来计算)
M = M + 12 if ct.month == 1 or ct.month == 2 else M
d = ct.day #取日数
i = 0 if ct.month % 2 == 1 else 6 #取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 #返回 干支纪日
return self.gan[G] + self.zhi[Z] def gz_hour(self): # 返回干支纪时(时辰)
ct = self.localtime #取当前时间
#计算支
Z = round((ct.hour/2) + 0.1) % 12 # 之所以加0.1是因为round的bug!! #返回 干支纪时(时辰)
return self.zhi[Z] def ln_year(self): # 返回农历年
year, _, _ = self.ln_date()
return year def ln_month(self): # 返回农历月
_, month, _ = self.ln_date()
return month def ln_day(self): # 返回农历日
_, _, day = self.ln_date()
return day def ln_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)
while delta_days >= tmp:
delta_days -= tmp
year += 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_month(year)):
(tmp, foo) = self._lunar_month_days(year, month)
if (delta_days < tmp):
return (0, 0, 0)
delta_days -= tmp
month += 1
(foo, tmp) = self._lunar_month_days(year, month) #计算日
day += delta_days
return (year, month, day) def ln_date_str(self):# 返回农历日期字符串,形如:农历正月初九
_, month, day = self.ln_date()
return '农历{}月{}'.format(self.lm[month-1], self.ld[(day-1)*2:day*2]) def ln_jie(self): # 返回农历节气
ct = self.localtime #取当前时间
year = ct.year
for i in range(24):
#因为两个都是浮点数,不能用相等表示
delta = self._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 #######################################################
# 下面皆为私有函数
####################################################### 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:
return flag & 0x0f
else:
return flag >> 4 def _lunar_month_days(self, lunar_year, lunar_month):
if (lunar_year < self.START_YEAR):
return 30 high, low = 0, 29
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 = 30
else:
high = 29 return (high, low) def _lunar_year_days(self, year):
days = 0
for i in range(1, 13):
(high, low) = self._lunar_month_days(year, i)
days += high
days += low
return days # 返回指定公历日期的儒略日(http://blog.csdn.net/orbit/article/details/9210413)
def _julian_day(self):
ct = self.localtime #取当前时间
year = ct.year
month = ct.month
day = ct.day if month <= 2:
month += 12
year -= 1 B = year / 100
B = 2 - B + year / 400 dd = day + 0.5000115740 #本日12:00后才是儒略日的开始(过一秒钟)*/
return int(365.25 * (year + 4716) + 0.01) + int(30.60001 * (month + 1)) + dd + B - 1524.5 # 返回指定年份的节气的儒略日数(http://blog.csdn.net/orbit/article/details/9210413)
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):
return 0.0 stJd = 365.24219878 * (year - 1900) + s_stAccInfo[st] / 86400.0 return base1900_SlightColdJD + stJd # 测试
def test(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实现的更多相关文章

  1. C#公历转农历算法

    C#公历转农历算法,高手们也可以改写一下让其更加有效率! Code/// <summary> /// LunDay 的摘要说明. /// 用法说明 /// 直接调用即可,比较简单 /// ...

  2. iOS 获取公历、农历日期的年月日

    iOS 获取公历.农历日期的年月日 介绍三种方法获取 Date (NSDate) 的年月日. 用 date 表示当前日期.测试日期为公历 2017 年 2 月 5 日,农历丁酉年,鸡年,正月初九. l ...

  3. Java 公历转农历,然后农历减一年(或者几天或者任意天),再把这个日期转成公历

    由于系统的提醒有可能是农历的今天或指定时间要用quartz 实现定时任务 公历转农历,然后农历减一年(或者几天或者任意天),再把这个日期转成公历. 网上很多农历转公历的程序都有问题,QQ.百度的也有 ...

  4. Andorid 之日历控件,可左右滑动,包含公历,农历,节假日等

    公司项目需要日历这个功能,经过查阅资料写了个demo,包含公历,农历,节假日等,还可左右滑动. 效果图: 代码: public class MainActivity extends AppCompat ...

  5. javascript 公历与农历相互转换工具类

    /** * 公历[1900-1-31,2100-12-31]时间区间内的公历.农历互转 * @charset UTF-8 * @Author Jea杨(JJonline@JJonline.Cn) * ...

  6. python3实现万年历(包括公历、农历、节气、节日)

    #!/usr/local/bin/python3 # coding=utf-8 # Created: 20/07/2012 # Copyright: http://www.cnblogs.com/tx ...

  7. C# 公历转农历

    /// <summary>     /// LunDay 的摘要说明.     /// 用法说明     /// 直接调用即可,比较简单     /// </summary> ...

  8. 公历和农历转换JS代码

    <!-- function CalConv(M) { FIRSTYEAR = 1936; LASTYEAR = 2031; LunarCal = [ new tagLunarCal(23, 3, ...

  9. JS:公历、农历互转

    先申明这段代码不是我写的,纯粹只是觉的比较好用,所以记录下来以后继续使用,也同样分享给大家,大家有更好的可以推荐给我,谢谢! function CalConv(M, dateStr) { if (da ...

随机推荐

  1. Replication--复制Token

    --创建tokenDECLARE @tokenID AS INT;EXEC sys.sp_posttracertoken @publication = @publication,@tracer_tok ...

  2. pandas模块安装问题笔记

    1. # pip install  pandas 引用 pandas 时,没有模块 ,进行模块安装,出现一推英文提示 结果 Collecting pandas Could not fetch URL ...

  3. js和java判断值为空的方式

    js方式判断值为空: name == ""; java方式判断值为空: name==null || name.trim().isEmpty();注:name==null要在前面,不 ...

  4. Oracle判断表、列、主键是否存在的方法

    在编写程序时,数据库结构会经常变化,所以经常需要编写一些数据库脚本,编写完成后需发往现场执行,如果已经存在或者重复执行,有些脚本会报错,所以需要判断其是否存在,现在我就把经常用到的一些判断方法和大家分 ...

  5. 【笔记】JS数据类型总结

    JavaScript有六种数据类型,分别为undefined.null.number.string.Boolean.object,前面的五种是基础数据类型,也称之为原始类型,也就是无法再细分的基本类型 ...

  6. Hibernate入门步骤及概念

    1.什么是Hibernate Hibernate是一个开发源代码的对象关系映射框架,它对JDBC进行非常轻量级的对象封装,使得程序员可以随心所欲地使用对象编程思维来操纵数据库.Hibernate可以应 ...

  7. 【理解】 Error 10053和 Error 10054

    1. 10053 这个错误码的意思是:  A established connection was aborted by the software in your host machine, 一个已建 ...

  8. mvc, web mvc, spring web mvc 区别

    1. MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用于组织代码用一种业务逻辑和数据显示分离的 ...

  9. mysql用户创建及授权

    一. 创建用户: 命令:CREATE USER 'username'@'host' IDENTIFIED BY 'password'; 说明:username - 你将创建的用户名, host - 指 ...

  10. Codeforces 1133 F2. Spanning Tree with One Fixed Degree 并查集+生成树

    好久没更新博客了,一直懒得动,这次更新一下. 题意大概是:给出一个图,求它的一个一号节点的度数恰好为D的生成树的方案. 一开始随便水了个乱搞贪心,不出意外并没有过. 仔细思考之后,对于这个问题我们可以 ...