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. RHEL7系统安装方式

    RHEL7系统安装方式包括: 1. 手动安装(介质在本地): 此种方式你可以通过图形界面操作定制你所需安装系统的配置及所需软件包等 优点:直观 缺点:效率低下,配置的东西多时易犯错 此种方式仅适用于初 ...

  2. 集训队日常训练20180525-DIV1

    A.2805 N*M的图,每次浇水(X1,Y1)-(X2,Y2)围成的矩形,问最后有多少点被浇水了. 暴力. #include<bits/stdc++.h> using namespace ...

  3. linux(centos) 下安装phpstudy 如何命令行进入mysql

    配置了phpstudy 可是进不去MySQL 老是报-bash: mysqld: command not found 解决方法:在Linux环境下运行:ln -s /phpstudy/mysql/bi ...

  4. 30分钟学webpack实战

    阅读目录 一:什么是webpack? 他有什么优点? 二:如何安装和配置 三:理解webpack加载器 四:理解less-loader加载器的使用 五:理解babel-loader加载器的含义 六:了 ...

  5. SQL优化系列(一)- 优化SQL

     优化SQL SQL开发人员从源代码中发现一条跑得很慢的SQL, 如何优化? DBA从AWR报告中发现一条跑得很慢的SQL,没有源代码或者不想修改源代码怎么办? SQL自动优化工具SQL Tuning ...

  6. 部署 LAMP (CentOS 7.2)

    摘自:https://help.aliyun.com/document_detail/50774.html 简介 LAMP指Linux+Apache+Mysql/MariaDB+Perl/PHP/Py ...

  7. Core Data Migration 之拆分Entity

    参考文章:http://blog.slalom.com/2010/01/08/splitting-an-entity-in-a-coredata-migration/ 最近自己做的背单词软件,在之前的 ...

  8. koa2路由

    注意:必须导出 文档地址:https://npm.taobao.org/package/koa-router 例: const router = require('koa-router')() rou ...

  9. SDUT-2144_最小生成树

    数据结构实验之图论九:最小生成树 Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 有n个城市,其中有些城市之间可以修建公 ...

  10. C++ 引用#include<math.h> 找不到动态库

    问题: 使用g++ 编译C++文件报错了,无法识别abs,可是我这文件中已经添加了#include<math.h>? 于是在指令中加入-lm g++ main.cpp AStar.cpp ...