Borax 1.3 Python常用工具包
最近在修改C++农历离线库,已经改完2020-2099年的数据,全是手动改,所以改的很累,改到不想入了。后来想用Python编个小程序实现自动修改,至少一些累人的事最好让程序来完成。于是又需要研究一下python的borax农历库,据说这个东西很历害,但我只用到了农历部分,以下是转载的关于农历的资料,我觉得写的比较好,留下备忘。
原文地址:https://www.bookstack.cn/read/borax/docs-guides-lunardate.md#%E6%97%A5%E6%9C%9F%E8%8C%83%E5%9B%B4
在此向原作者表示感谢!
目录
lunardate 模块
概述
常量定义
日期范围
创建日期对象
属性和显示
属性表
格式化
公历转化
日期推算
日期比较
序列化与存储
pickle协议支持
sqlite3自定义字段
LCalendars工具接口
参考资料
lunardate 模块
模块:
borax.calendars.lunardate
协议:GPLv3
概述
lunardate
模块是一个处理中国农历日期的工具库。支持1900 - 2100 农历年范围的日期、干支纪年、节气等历法信息。
本模块的数据和算法引用自项目 jjonline/calendar.js ,具体内容包括:
- 1900-2100年农历月份信息
- 干支纪年算法
关于本模块的更多资料可参考文章 《Borax-Lunar开发笔记》。
常量定义
lunardate
提供了下列的模块级常量。
- lunardate.MIN_LUNAR_YEAR
农历可表示的最大年份,值为 2100 。
- lunardate.MAX_LUNAR_YEAR
农历可表示的最小年份,值为 1900 。
- lunardate.MIN_SOLAR_DATE
农历可表示的日期下限,值为 datetime.date(1900, 1, 31)
,日期同 LunarDate.min
。
- lunardate.MAX_SOLAR_DATE
农历可表示的日期下限,值为 datetime.date(2101, 1, 28)
,日期同 LunarDate.max
。
- lunardate.MAX_OFFSET
农历日期的最大偏移量,值为73411。
日期范围
LunarDate
实例表示一个具体日期,该类可以表示的日期起止范围如下表:
项目 | 起始日 | … | 2100年 | 2101年 | … | 截止日 |
---|---|---|---|---|---|---|
公历 | 1990年1月31日 | … | 2100年12月31日 | 2101年1月1日 | … | 2101年1月28日 |
农历 | 1900年正月初一 | … | 2100年腊月初一 | 2100年腊月初二 | … | 2100年腊月廿九 |
offset | 0 | … | 73383 | 73384 | … | 73411 |
干支 | 庚午年丙子月壬辰日 | … | 庚申年戊子月丁未日 | 庚申年戊子月戊申日 | … | 庚申年己丑月乙亥日 |
创建日期对象
可以通过以下几种方法创建。
▶ 农历日期
依次传入农历年、月、日、闰月标志等4个参数创建一个新对象,其中闰月标志可省略,表示为平月。
>>>from borax.calendars.lunardate import LunarDate
>>>LunarDate(2018, 7, 1)
LunarDate(2018, 7, 1, 0)
▶ 公历日期
将公历日期转化为农历日期。
>>>ld = LunarDate.from_solar_date(2018, 8, 11)
>>>ld
LunarDate(2018, 7, 1, 0)
▶ 特定的日期
获取今日/昨日/明日的农历日期。
>>>LunarDate.today()
LunarDate(2018, 7, 1, 0)
>>>LunarDate.yesterday()
LunarDate(2018, 6, 29, 0)
>>>LunarDate.tomorrow()
LunarDate(2018, 7, 2, 0)
lunardate
模块可用的日期上下限
>>>LunarDate.min
LunarDate(1990, 1, 1, 0)
>>>LunarDate.max
LunarDate(2100, 12, 29, 0)
属性和显示
属性表
和公历日期对象 datetime.date
类似,LunarDate
是不可变对象(Immutable Object),可以作为字典的键值。全部属性如下表(以 LunarDate(2018, 6, 26, False)
为例):
属性 | 类型 | 描述 | 示例值 | 格式描述符 | 备注 |
---|---|---|---|---|---|
year |
int
|
农历年 | 2018 | %y | |
month |
int
|
农历月 | 6 | %m | |
day |
int
|
农历日 | 26 | %d | |
leap |
bool
|
是否闰月 | False | %l | (1) |
offset |
int
|
距下限的偏移量 | 43287 | - | |
term |
str 或 None
|
节气名称 | 立秋 | %t | |
cn_year |
str
|
中文年 | 二〇一八年 | %Y | (2) |
cn_month |
str
|
中文月 | 六月 | %M | (2) |
cn_day |
str
|
中文日 | 廿六 | %D | (2) |
gz_year |
str
|
干支年份 | 戊戌 | %o | |
gz_month |
str
|
干支月份 | 庚申 | %p | |
gz_day |
str
|
干支日 | 辛未 | %q | |
animal |
str
|
年生肖 | 狗 | %a | |
- |
str
|
两位数字的月份 | 06 | %A | |
- |
str
|
两位数字的日期 | 26 | %B | |
cn_day_calendar |
str
|
用于日历显示的中文日 | 26 | %F | v1.3.0新增 (3) |
str(ld)
|
str
|
默认表示法 | LunarDate(2018, 6, 26, False) | - | |
ld.cn_str()
|
str
|
汉字表示法 | 2018年六月廿六 | %C | |
ld.gz_str()
|
str
|
干支表示法 | 戊戌年庚申月辛未日 | %G |
备注信息:
- (1) ‘%l’ 将闰月标志格式化为数字,如“0”、“1”
- (2) ‘%Y’、’%M’、’%D’ 三个中文名称不包含“年”、“月”、“日”后缀汉字
- (3) ‘%F’ 将“初一”改为相应的中文月份,如“七月”、“闰六”、“冬月”、“闰冬”。
格式化
- LunarDate.strftime(fmt)
strftime
通过描述符(Directive)格式化给定的日期字符串。在“属性”一节中已经列出所有属性的格式描述符。
例子:
>>>today = LunarDate.today()
>>>today.strftime('%Y-%M-%D')
'二〇一八-六-廿六'
>>>today.strftime('今天的干支表示法为:%G')
'今天的干支表示法为:戊戌年庚申月辛未日'
公历转化
- LunarDate.to_solar_date()
将当前日期转化为公历日期
>>> ld = LunarDate(2018, 6, 26, False)
>>>ld.to_solar_date()
datetime.date(2018, 8, 7)
日期推算
▶ 加减操作符
LunarDate
支持和 datetime.timedelta
或 datetime.date
进行加减计算。
左操作数类型 | 操作符 | 右操作数类型 | 结果类型 |
---|---|---|---|
LunarDate
|
+ |
datetime.timedelta
|
LunarDate
|
datetime.timedelta
|
+ |
LunarDate
|
LunarDate
|
LunarDate
|
- |
datetime.timedelta
|
LunarDate
|
datetime.date
|
- |
LunarDate
|
datetime.timedelta
|
LunarDate
|
- |
datetime.date
|
datetime.timedelta
|
LunarDate
|
- |
LunarDate
|
datetime.timedelta
|
例子:
>>> LunarDate(2018, 6, 3) + timedelta(days=3)
LunarDate(2018, 6, 6, 0)
>>> LunarDate(2018, 6, 18) - LunarDate(2018, 6, 3)
timedelta(days=15)
▶ 日期推算
before/after函数
返回向前/向后推算 n 天的日期。n 允许取负值,即 ld.after(5)
和 ld.before(-5)
返回表示同一个日期的实例。
>>> ld = LunarDate(2018, 6, 3)
>>>ld.after(3)
LunarDate(2018, 6, 6, 0)
>>>ld.before(2)
LunarDate(2018, 6, 1, 0)
>>>ld.after(-2)
LunarDate(2018, 6, 1, 0)
replace函数
replace(self, *, year=None, month=None, day=None, leap=None)
返回一个替换给定值后的日期对象。所有参数必须以关键字形式传入。如果该日期不存在,将抛出 ValyeError
异常。
>>>ld = LunarDate(2018, 5, 3)
>>>ld.replace(year=2019)
LunarDate(2019, 5, 3, 0)
>>>ld.replace(leap=True)
ValueError: month out of range
日期比较
LunarDate
支持和 datetime.date
对象进行比较,对象所代表的日期更新其“数值”更大。
>>>LunarDate(2018, 6, 2) > LunarDate(2018, 6, 14)
False
>>>LunarDate(2018, 6, 2) > date(2018, 6, 2)
True
序列化与存储
pickle协议支持
LunarDate
对象支持 pickle 序列化。
import pickle
from borax.calendars.lunardate import LunarDateld = LunarDate.today()
with open('data.pickle', 'wb') as f:
pickle.dump(ld, f)with open('data.pickle', 'rb') as f:
l2 = pickle.load(f)
print(l2) # LunarDate(2018, 7, 24, 0)
sqlite3自定义字段
LunarDate
继承自 store.EncoderMixin
接口,为 sqlite3 自定义字段提供支持,更多细节参考 sqlite3文档。
下面是一个简单的例子:
import sqlite3from borax.calendars.lunardate import LunarDatedef adapt_lunardate(ld):
return ld.encode()sqlite3.register_adapter(LunarDate, adapt_lunardate)
sqlite3.register_converter("lunardate", LunarDate.decode)con = sqlite3.connect(":memory:", detect_types=sqlite3.PARSE_DECLTYPES)
cur = con.cursor()
cur.execute('CREATE TABLE member (pid INT AUTO_INCREMENT PRIMARY KEY,birthday lunardate);')ld = LunarDate(2018, 5, 3)
cur.execute("INSERT INTO member(birthday) VALUES (?)", (ld,))cur.execute("SELECT pid, birthday FROM member;")
my_birthday = cur.fetchone()[1]cur.close()
con.close()print(my_birthday.year) # 2018
print(my_birthday.month) # 5
print(my_birthday.day) # 3
print(my_birthday.leap) # 0
LCalendars工具接口
LCalendars
提供了一系列的工具方法。
- LCalendars.leap_month(year: int) -> int
返回 year 年的闰月月份,范围为 [0,12] ,0 表示该年无闰月。
- LCalendars.is_leap_month(year: int, month: int) -> bool
判断 year 年 month 月是否为闰月。该方法已废弃,可使用 LCalendars.leap_month(year) == month
表达式代替。
- LCalendars.ndays(year: int, month: Optional[int] = None, leap: Leap = False) -> int
返回X年或者X年X月的天数;如输入的年月不存在,将抛出 ValueError
异常。
例子:
>>>from borax.calendars.lunardate import LCalendars
>>>LCalendars.ndays(2018)
354
>>>LCalendars.ndays(2018, 12)
30
>>>LCalendars.ndays(2017, 6, 1)
30
>>>LCalendars.ndays(2200)
ValueError: year out of range [1900, 2100]
>>>LCalendars.ndays(2017, 7, 1)
ValueError: Invalid month for the year 2017
- LCalendars.iter_year_month(year: int) -> Iterator[Tuple[int, int, int]]
迭代X年的月份信息,元素返回 (月份, 该月的天数, 闰月标记) 的元祖。
例子:
>>>from borax.calendars.lunardate import LCalendars
>>>list(LCalendars.iter_year_month(2017))
[(1, 29, 0), (2, 30, 0), (3, 29, 0), (4, 30, 0), (5, 29, 0), (6, 29, 0), (6, 30, 1), (7, 29, 0), (8, 30, 0), (9, 29, 0), (10, 30, 0), (11, 30, 0), (12, 30, 0)]
- LCalendars.create_solar_date(year: int, term_index: Optional[int] = None, term_name: Optional[str] = None) -> datetime.date
根据节气名称或者序号获取对应的公历日期对象(dateitime.date
)。term_index
和 term_name
只需传入一个参数,
term_index
取值为 0-23 。其中 小寒的序号为0,立春的序号为2,…冬至的序号为23。
>>>LCalendars.create_solar_date(2019, term_name='清明')
2019-04-05
- LCalendars.delta(date1:MDate, date2:MDate) -> int
计算两个日期相隔的天数,即 (date1 - date2).days
。
参考资料
- 香港天文台农历信息
- 农历维基词条
- jjonline/calendar.js
- lidaobing/python-lunardate
Borax 1.3 Python常用工具包相关推荐
- Python常用工具包
python常用包的介绍 1.NumPy数值计算 NumPy是使用Python进行科学计算的基础包,Numpy可以提供数组支持以及相应的高效处理函数,是Python数据分析的基础,也是SciPy.Pa ...
- Python自用工具包PyTls
我们搞了个python的工具包PyTls. 做这件事的初衷是发生了一个星期要用python同时开发3个项目的情况,我发现了两个现象:1.有很多定制化的需求是极度高频反复重写的:2.有很多功能之前写过, ...
- 2转单通道 python_机器学习用Python—Python集成工具包Anaconda安装步骤
近几年来,机器学习以及深度学习的研究异常火热,机器学习和深度学习也逐渐渗透到各个领域,当然,脑科学领域也不例外.利用机器学习和深度学习技术解决脑科学领域中的问题,成为目前最为火热的研究方向之一.而神经 ...
- Python常用扩展包
一. Python常用扩展包 参考张良均的<Python数据分析与挖掘实战>,下图展示了常见的Python扩展包. 常用的包主要包括: 1.Numpy ...
- anaconda python_机器学习用Python—Python集成工具包Anaconda安装步骤
近几年来,机器学习以及深度学习的研究异常火热,机器学习和深度学习也逐渐渗透到各个领域,当然,脑科学领域也不例外.利用机器学习和深度学习技术解决脑科学领域中的问题,成为目前最为火热的研究方向之一.而神经 ...
- python 常用包_七月在线—Python和数据分析Lesson 1
写在前面 偶尔间看到朋友推荐这门课程,出于好奇打开看了一下课程目录,感觉对于想系统学习一下Python数据分析的朋友是不错的入门课程.于是也加入学习了一下. 目前看了第一课时,感觉很不错.附课程目录. ...
- 8个流行的Python可视化工具包。
喜欢用 Python 做项目的小伙伴不免会遇到这种情况:做图表时,用哪种好看又实用的可视化工具包呢?之前文章里出现过漂亮的图表时,也总有读者在后台留言问该图表时用什么工具做的.下面,作者介绍了八种在 ...
- Python常用第三方库
Python常用第三方库 一. 文件读写 二.网络抓取和解析 三.数据库连接 四.数据清洗转换 五.数据计算和统计分析 六.自然语言处理和文本挖掘 七.图像和视频处理 八.音频处理 九.数据挖掘/机器 ...
- Python 常用的标准库以及第三方库有哪些?
Python常用库大全,看看有没有你需要的. 环境管理 管理 Python 版本和环境的工具 p – 非常简单的交互式 python 版本管理工具. pyenv – 简单的 Python 版本管理工具 ...
最新文章
- 99%高精度、毫秒级延迟,AI便携式神经假肢让截肢14年患者运动自如
- 50个令人大开眼界的 Matplotlib 可视化项目
- PHP获取CentOS服务状态,简单linux下php获取服务器状态代码
- 从fastjson的TypeReference用法,推导如何实现泛型反射
- 人员梯度培养_干部梯队培养方案
- Samba服务器(一):windows访问samba服务器共享文件的简单实现(图文并茂)
- 第二阶段冲刺-个人总结04
- 抖音电商“双11”:品质国货和地方农特产成亮点
- Linux Storage I/O Stack v1.0
- MySQL字符集小结
- beta阶段——项目复审
- 2022,火山引擎的云上第一“子”,为何是视频?
- [转载] css border-collapse
- FFmpeg中AVFrame中width与linesize的关系
- java day56【 Mybatis 延迟加载策略 、 Mybatis 缓存、Mybatis 注解开发 】
- 如何在水经注会员中心购买流量下载地图
- torch.device用法总结
- ubuntu18.04安装PCL点云库踩坑指南
- 金蝶迷你版所有数据引出excel没有反应,如何处理
- Java开发工程师大厂面试常见问题总结(应届生版)
热门文章
- 手撸web框架即引入框架思想,wsgierf模块,动静态网页,模板语法jinja2,python三大主流web框架,django安装,三板斧...
- IMX6ULL MINI用ov5640摄像头
- Field shiroService in com.bbzd.mes.shiro.auth.AuthRealm required a bean of type ‘xxxService‘ that...
- Trace Related
- 网赚项目,什么才是长期有效的引流方法?
- 1346. 回文平方
- python自动化测试实战 虫师_《Selenium2自动化测试实战--基于Python语言》 --即将面市...
- strncat越界,踩内存
- NumPy 广播(Broadcast)与pandas基础知识
- 自然语言处理 第三期 【任务3 - 特征提取】时长:2天