python实现以立春为起点n为周期任意日期所在的日期区间
python实现以立春为起点n为周期任意日期所在的日期区间
需求
话不多说,直接上具体需求。
'''
以每年的立春作为起始点,每N天为一个单元,任给一个日期,返回该日期所在单元的起始和结束日期。例如:N=3, 输入日期20180208,返回20180207,20180209(2018年的立春是20180204,所以第一个单元是20180204-20180206,第二个单元是 20180207-20180209,依次类推)
'''
分析
上边的需求乍一看还挺简单,但是具体实现起来还是需要对time模块、datatime模块、sxtwl模块的熟练应用。
首先呢,要求以立春为起始点,那么说我们可以找出立春在一年中的第num_day_0天,同时我们也找出我们输入的日期在一年中的第num_day_x天。这样一来,我们就可以计算出这两天相差的天数day_diff,使用day_diff除以周期N,就可以确定我们输入的日期是在周期日期区间的边线还是在日期区间的中间。然后我们就可以根据输入日期在一年中的第num_day_x以及相差的天数day_diff来计算出需要的日期区间,最麻烦的就在于根据num_day求日期了。
其中的难点我认为有两点,一是根据输入的年份来确定立春的阳历日期,二就是计算日期区间了。当然了,这些对大神来说都是so easy!下来我们看代码。
实现
立春日期
立春日期的确定,我费了不少劲,网上各种查找,偶然间看到了sxtwl模块,于是找到了它的官方文档,参考官方文档中的演示代码,写下了下边的代码,其实这个模块我也没看得很明白,也没怎么看,就发现我使用jqmc方法可以确定立春日期。
这里解释下,我多次实验发现,当day.jqmc的值为3时,这天就为立春,其他日期返回值为0。附上官方文档的部分资料:
'''
jqmc = ["冬至", "小寒", "大寒", "立春", "雨水", "惊蛰", "春分", "清明", "谷雨", "立夏", "小满", "芒种", "夏至", "小暑", "大暑", "立秋", "处暑","白露", "秋分", "寒露", "霜降", "立冬", "小雪", "大雪"]
'''
看完这个列表你就能发现,立春的索引为3,于是就这样含糊的写出了计算立春的代码。
import sxtwl
def getTerms(year, month, day):
lunar = sxtwl.Lunar() # 实例化日历库
day = lunar.getDayBySolar(year, month, day)
return day.jqmc # 0为非春分;3为春分
num_day转日期
接下来就是这个计算在一年中第多少天的问题,其实这个问题并不难,因为我之前就是知道使用time模块就可以查得到。但是问题是在于知道一年中的第多少天了,怎么得出这一天在一年中的阳历日期呢。下面的代码我也是在网上找了别人的代码参考的。
import datetime def out_date(year, day):
fir_day = datetime.datetime(year, 1, 1) # 每年的第一天
zone = datetime.timedelta(days=day - 1) # 日期差值day_diff
return datetime.datetime.strftime(fir_day + zone, "%Y-%m-%d") # 得到日期
主代码
import time
from spring_begins import getTerms
from num_day import out_date def input_time(n, inp_time): # 构造两个年份字典,用来判断输入时间的合法性
common_year = {'': 31, '': 28, '': 31, '': 30, '': 31, '': 30, '': 31, '': 31, '': 30,
'': 31, '': 30, '': 31}
leap_year = {'': 31, '': 29, '': 31, '': 30, '': 31, '': 30, '': 31, '': 31, '': 30,
'': 31, '': 30, '': 31}
# 判断输入的日期是不是纯数字组成的
if not inp_time.isdigit():
return print('输入的内容有误(不是纯数字)!!!')
# 判断输入日期的长度
if len(inp_time) != 8:
return print('输入的内容有误(长度有误)!!!')
# 判断输入的月份是否在正确范围内
if month_judge(inp_time[4:6]):
pass
else:
return print('月份输入有误!!!')
# 判断平年闰年
if common_or_leap(int(inp_time[:4])):
day_judge(inp_time[-2:], inp_time[4:6], leap_year) # 判断n输入的合法性,n最大等于一年的总天数
if int(n) > 366:
return print('N输入超范围!!!')
else:
day_judge(inp_time[-2:], inp_time[4:6], common_year)
if int(n) > 365:
return print('N输入超范围!!!')
# 通过查资料得出立春在每年的二月的三号到八号之间,所以遍历这六天来确定最终的日期
for i in [3, 4, 5, 6, 7, 8]:
if getTerms(int(inp_time[:4]), 2, i) == 3:
spring_b = f'{inp_time[:4]}020{i}' # 得到立春日期
# 立春的格式化时间,后续取一年中的第num_day用
struct_time_S = time.strptime(f'{spring_b[:4]}-{spring_b[4:6]}-{spring_b[-2:]}', '%Y-%m-%d') # 输入日期的格式化时间
struct_time = time.strptime(f'{inp_time[:4]}-{inp_time[4:6]}-{inp_time[-2:]}', '%Y-%m-%d') # 输入日期与立春的天数差day_diff
yushu = (struct_time.tm_yday - struct_time_S.tm_yday) % int(n) # 输出结果
print((out_date(int(inp_time[:4]), struct_time.tm_yday - yushu),
out_date(int(inp_time[:4]), struct_time.tm_yday - 1 - yushu + int(n)))) def common_or_leap(years):
'''
判断日期的平闰年
'''
if years % 4 == 0 & years % 100 != 0 or years % 400 == 0:
return True def month_judge(months):
'''
判断日期中月份的合法性
'''
if int(months) <= 12:
return True def day_judge(days, months, year_kind):
'''
判断日期中日的合法性
'''
if int(days) <= year_kind[months]:
return True if __name__ == '__main__':
n = input('请输入周期N>>>').strip()
inp_time = input('请输入日期(格式20160920)>>>').strip()
input_time(n, inp_time)
以上就是我写这个需求是遇到的问题以及最终的结果,其中可能存在小的问题,本代码仅供参考。
python实现以立春为起点n为周期任意日期所在的日期区间的更多相关文章
- Python 计算当真因子个数为偶数个时为幸运数,计算区间内幸运数之和
晚饭后朋友发来个问题,正好无事做,动手写了一下 若一个正整数有偶数个不同的真因子,则称该数为幸运数.如4含有2个真因子为 1 和 2 .故4是幸运数.求[2,100]之间的全部幸运数之和. 常规思路 ...
- 利用Python进行数据分析笔记-时间序列(时区、周期、频率)
此文对Python中时期.时间戳.时区处理等阐述十分清楚,特别值得推荐学习. 原文链接:https://blog.csdn.net/wuzlun/article/details/80287517
- PyQt(Python+Qt)学习随笔:exit code 1073741845与槽函数所在对象不能定义同名实例方法问题
最近做了几次测试,在PyQt中如果使用与槽函数同名的实例方法可能会导致不可控的错误. 案例1:如果两个信号映射到同名的槽函数,虽然参数不一样,但真正响应的槽函数是最后定义的槽函数,具体案例请见< ...
- Python 之 时间字符串、时间戳、时间差、任意时间字符串转换时间对象
1. 时间字符串 --> 时间戳 1) time 模块 timestring = '2016-12-21 10:22:56' print time.mktime(time.strptime(ti ...
- python 获取整点时间戳,半整点时间戳 ,同时将时间戳转换成 日期时间
import time, datetime def gettime(): for x in range(24): a = datetime.datetime.now().strftime(" ...
- 流畅的Python——切片
2.4 切片 在 Python 里,像列表(list).元组(tuple)和字符串(str)这类序列类型都支持切片操作,但是实际上切片操作比人们所想象的要强大很多. 在我个人的使用经历来看,在算法实践 ...
- 学习python第三天单行函数
1.去重:distinct关键字 需求:查看公司一共有多少部门? select department_id from employees;此代码会查出107条记录,存在部门重复的问题! select ...
- Python入门 —— 05时间日期处理小结
此文多涉及基础,如果想要深入理解则到文末,有提供链接 涉及对象 1. datetime 2. timestamp 3. time tuple 4. string 5. date - datetime基 ...
- python之字符串处理 2014-4-5
#字符串 p62 13:20pm-15:20 上一章讲的所有的序列化操作对于字符串同样适用 不过字符串不可变 所以无法使用分片赋值 1.字符串格式化 >>> format=" ...
随机推荐
- 多机MySQL一主双从详细安装主从复制
多机MySQL一主双从详细安装 一.复制的工作原理 要想实现AB复制,那么前提是master上必须要开启二进制日志 1.首先master将数据更新记录到二进制日志文件 2.从slave start开始 ...
- 学习Python笔记---if 语句
条件测试 每条if语句的核心都是一个值为True或False的表达式,这种表达式被称为条件测试.Python根据条件测试的值True还是False来决定是否执行if语句中的代码.如果条件测试的值为Tr ...
- NKOJ1472 警卫安排
P1472警卫安排 时间限制 : 10000 MS 空间限制 : 65536 KB 问题描述 一个重要的基地被分为n个连通的区域.出于某种神秘的原因,这些区域以一个区域为核心,呈一颗树形分布. ...
- 考试总结 模拟27(W)
心得:太弱了,T1问题:理解错了题,矿石可以放到同一处,,太弱了,小凯的疑惑,没什么印象T2问题:拆式子T3问题:换根dp的思想模拟9T1+T2
- (二)SpringBoot功能
web开发 spring boot web开发非常的简单,其中包括常用的json输出.filters.property.log等 json 接口开发 在以前的spring 开发的时候需要我们提供jso ...
- WPF 触发器例子
WPF的触发器很强大,这里简单附上触发器的一个小例子,分别用XMAL和CS代码来实现一个功能,鼠标悬停在button上时改变字体颜色 1.XMAL代码如下: <Window x:Class=&q ...
- UML时序图(Sequence Diagram)学习笔记
什么是时序图时序图(Sequence Diagram),又名序列图.循序图,是一种UML交互图.它通过描述对象之间发送消息的时间顺序显示多个对象之间的动态协作. 让我们来看一看visio2016对时序 ...
- Linux SSH远程链接 短时间内断开
Linux SSH远程链接 短时间内断开 操作系统:RedHat 7.5 问题描述: 在进行SSH链接后,时不时的就断开了 解决方案: 修改 /etc/ssh/sshd_config 文件,找到 Cl ...
- spring拦截器Interceptor
在Spring Boot中,拦截器可以分为两种类型: 一是WebMVC,负责拦截请求,类似于过滤器,对用户的请求在Controller接收前进行处理,在Controller处理完成后加工结果等.使用时 ...
- python KMP算法介绍