python时间和周期_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,于是就这样含糊的写出了计算立春的代码。

importsxtwldefgetTerms(year, month, day):

lunar= sxtwl.Lunar() #实例化日历库

day =lunar.getDayBySolar(year, month, day)return day.jqmc #0为非春分;3为春分

num_day转日期

接下来就是这个计算在一年中第多少天的问题,其实这个问题并不难,因为我之前就是知道使用time模块就可以查得到。但是问题是在于知道一年中的第多少天了,怎么得出这一天在一年中的阳历日期呢。下面的代码我也是在网上找了别人的代码参考的。

importdatetimedefout_date(year, day):

fir_day= datetime.datetime(year, 1, 1) # 每年的第一天

zone= datetime.timedelta(days=day - 1) # 日期差值day_diffreturn datetime.datetime.strftime(fir_day + zone, "%Y-%m-%d") # 得到日期

主代码

importtimefrom spring_begins importgetTermsfrom num_day importout_datedefinput_time(n, inp_time):

# 构造两个年份字典,用来判断输入时间的合法性

common_year= {'01': 31, '02': 28, '03': 31, '04': 30, '05': 31, '06': 30, '07': 31, '08': 31, '09': 30,'10': 31, '11': 30, '12': 31}

leap_year= {'01': 31, '02': 29, '03': 31, '04': 30, '05': 31, '06': 30, '07': 31, '08': 31, '09': 30,'10': 31, '11': 30, '12': 31}

# 判断输入的日期是不是纯数字组成的if notinp_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))))defcommon_or_leap(years):

'''

判断日期的平闰年

'''if years % 4 == 0 & years % 100 != 0 or years % 400 ==0:returnTruedefmonth_judge(months):

'''

判断日期中月份的合法性

'''if int(months) <= 12:returnTruedefday_judge(days, months, year_kind):

'''

判断日期中日的合法性

'''if int(days) <=year_kind[months]:returnTrueif __name__ == '__main__':

n= input('请输入周期N>>>').strip()

inp_time= input('请输入日期(格式20160920)>>>').strip()

input_time(n, inp_time)

以上就是我写这个需求是遇到的问题以及最终的结果,其中可能存在小的问题,本代码仅供参考。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值