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为周期任意日期所在的日期区间的更多相关文章

  1. Python 计算当真因子个数为偶数个时为幸运数,计算区间内幸运数之和

    晚饭后朋友发来个问题,正好无事做,动手写了一下 若一个正整数有偶数个不同的真因子,则称该数为幸运数.如4含有2个真因子为 1 和 2 .故4是幸运数.求[2,100]之间的全部幸运数之和. 常规思路 ...

  2. 利用Python进行数据分析笔记-时间序列(时区、周期、频率)

    此文对Python中时期.时间戳.时区处理等阐述十分清楚,特别值得推荐学习. 原文链接:https://blog.csdn.net/wuzlun/article/details/80287517

  3. PyQt(Python+Qt)学习随笔:exit code 1073741845与槽函数所在对象不能定义同名实例方法问题

    最近做了几次测试,在PyQt中如果使用与槽函数同名的实例方法可能会导致不可控的错误. 案例1:如果两个信号映射到同名的槽函数,虽然参数不一样,但真正响应的槽函数是最后定义的槽函数,具体案例请见< ...

  4. Python 之 时间字符串、时间戳、时间差、任意时间字符串转换时间对象

    1. 时间字符串 --> 时间戳 1) time 模块 timestring = '2016-12-21 10:22:56' print time.mktime(time.strptime(ti ...

  5. python 获取整点时间戳,半整点时间戳 ,同时将时间戳转换成 日期时间

    import time, datetime def gettime(): for x in range(24): a = datetime.datetime.now().strftime(" ...

  6. 流畅的Python——切片

    2.4 切片 在 Python 里,像列表(list).元组(tuple)和字符串(str)这类序列类型都支持切片操作,但是实际上切片操作比人们所想象的要强大很多. 在我个人的使用经历来看,在算法实践 ...

  7. 学习python第三天单行函数

    1.去重:distinct关键字 需求:查看公司一共有多少部门? select department_id from employees;此代码会查出107条记录,存在部门重复的问题! select ...

  8. Python入门 —— 05时间日期处理小结

    此文多涉及基础,如果想要深入理解则到文末,有提供链接 涉及对象 1. datetime 2. timestamp 3. time tuple 4. string 5. date - datetime基 ...

  9. python之字符串处理 2014-4-5

    #字符串 p62 13:20pm-15:20 上一章讲的所有的序列化操作对于字符串同样适用 不过字符串不可变 所以无法使用分片赋值 1.字符串格式化 >>> format=" ...

随机推荐

  1. 关于python的元组操作

    关于元组: 元组和列表是类似的,但是元组中的数据是不可以修改的. 元组是一对 () 元组操作: 元组是不可以修改的所以对元组的操作极少 定义空元组(因为元组一旦创建,数据不可被修改,所以极少创建空元组 ...

  2. Ocelot(二)- 请求聚合

    原文:Ocelot(二)- 请求聚合 Ocelot(二)- 请求聚合与负载均衡 作者:markjiang7m2 原文地址:https://www.cnblogs.com/markjiang7m2/p/ ...

  3. Thinkphp5.0 模型hasOne、hasMany、belongsTo详解

    ThinkPHP5有关联模型的操作,但有部分初学者对数据表中常见的几种表与表的关系还存在着问题,所以使用不好关联查询. 这里将hasOne.hasMany.belongsTo进行一个详细举例说明. 首 ...

  4. iostat统计信息

    用途:报告中央处理器(CPU)统计信息和整个系统.适配器.tty 设备.磁盘和 CD-ROM 的输入/输出统计信息. 语法:iostat [ -c | -d ] [ -k ] [ -t | -m ] ...

  5. 洛谷P1029 最大公约数和最小公倍数问题 [2017年6月计划 数论02]

    P1029 最大公约数和最小公倍数问题 题目描述 输入二个正整数x0,y0(2<=x0<100000,2<=y0<=1000000),求出满足下列条件的P,Q的个数 条件: 1 ...

  6. js经典校验之注册与登录校验

    平时都专注于后台功能的实现和逻辑需求的分析及数据库方面的设计,很少关注前端的设计,而项目开发过程中专门负责后台是不太可能的事,所以前端我们也需要会用,除了漂亮的首页等其他的交给美工来做,一些功能性的东 ...

  7. ubuntu设置终端命令历史记录

    ----------------------------------------------- HISTTIMEFORMAT='%F %T ' # 使用HISTTIMEFORMAT在历史中显示TIME ...

  8. C++ operator new和new operator的区别

    new operator 当你写这种代码: string *ps = new string("Memory Management"); 你使用的new是new  operator. ...

  9. 解决pycharm新建工程项目都需要重新安装库问题

    在新建一个工程项目后,发现之前安装的库均不在了.想要使用的情况下还得重新安装.这样也太不智能了,一定会有解决的办法.查找相关文档后,发现在新建工程项目的时候需要进行选择是否使用以前的环境. 选择已存在 ...

  10. BZOJ1076奖励关题解

    链接 很容易想到状压,f[i][s]表示前i个选择的箱子集合为s的最大期望 果断wa了,因为有一些不合法的状态,譬如f[1][1111001]这样的状态 这样的状态不好排除,所以改用倒推 用f[i][ ...