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=" ...
随机推荐
- hibernate分页功能
设置开始位置无效 设置终止位置是可以的 设置完之后,并没有分页 问题解决 https://blog.csdn.net/qq_39859824/article/details/77902488 http ...
- 洛谷P4145 上帝造题的七分钟2 / 花神游历各国(重题:洛谷SP2713 GSS4 - Can you answer these queries IV)
题目背景 XLk觉得<上帝造题的七分钟>不太过瘾,于是有了第二部. 题目描述 "第一分钟,X说,要有数列,于是便给定了一个正整数数列. 第二分钟,L说,要能修改,于是便有了对一段 ...
- Dijkstra,floyd,spfa三种最短路的区别和使用
这里不列举三种算法的实现细节,只是简单描述下思想,分析下异同 一 Dijkstra Dijkstra算法可以解决无负权图的最短路径问题,只能应付单源起点的情况,算法要求两个集合,开始所有点在第二个集合 ...
- Sublime Text Version 3.2.1(Build 3207)注册
Sublime Text Version 3.2.1, Build 3207 一. host添加地址 C:\Windows\System32\drivers\etc\hosts 127.0.0.1 l ...
- SourceTree windows免注册免登陆使用方法
问题描述: 安装SourceTree后,首次使用时,需要登录账号:但我们在注册或登录时,可能根本无法打开网页,导致不能进入. 如下截图: 解决方法: 在目录C:\Users\XXXXX\AppData ...
- Sorry, the page you are looking for is currently unavailable. Please try again later. Nginx
访问html可以正常访问,但是访问PHP则错误,原因: nginx不能正常通过FastCGI结果访问PHP 查看php-fpm是否正常运行: 果然没有,重启php-fpm: /etc/init.d/p ...
- JRE System Library、Referenced Libraries、Web App Libraries的含义
JRE System Library.Referenced Libraries.Web App Libraries 这三个都是jar包的存放集合. JRE System Library:指Java S ...
- POJ 1150 The Last Non-zero Digit 数论+容斥
POJ 1150 The Last Non-zero Digit 数论+容斥 题目地址: id=1150" rel="nofollow" style="colo ...
- C++之自定义key类型,重载操作符
#include <map>#include <string>using namespace std;class MyString{ public:MyString(){m_s ...
- ELK学习之jdk和jre的区别
JRE: Java Runtime EnvironmentJDK:Java Development KitJRE顾名思义是java运行时环境,包含了java虚拟机,java基础类库.是使用java语言 ...