IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Python知识库 -> 日期范围的通配符表示-附python代码 -> 正文阅读

[Python知识库]日期范围的通配符表示-附python代码

本文记录了将给定的日期范围用通配符表示的相关内容,欢迎与我沟通联系(zhaoliang19960421@outlook.com)
如果在使用中发现程序输入与结果不符,欢迎与我沟通

在hdfs中数据以date为分区进行分别保存,采用MapReduce框架进行大数据开发时在路径输入中,没有在hive\sql中的 date between . and . 的写法,与之对应的是将日期采用通配符的形式进行输入
case1 日期范围是:20220101 20221231

解释:需要输入的是2022年一整年的数据,所以采用通配符的表达方式为2022*

case2 日期范围是 : 20210101 20210331

解释:需要输入的2021年,1月、2月、3月的全部日期,采用通配符的表示方式是 '202101*', '202102*', '202103*'

case3 日起范围是:20200104 20210302

解释:需要输入的是,从1月4号到1月底,2月整月、3月1号,3月2号的日期,采用通配符的表示方式是 ['20200104', '20200105', '20200106', '20200107', '20200108', '20200109', '2020011*', '2020012*', '2020013*', '202002*', '202003*', '202004*', '202005*', '202006*', '202007*', '202008*', '202009*', '202010*', '202011*', '202012*', '202101*', '202102*', '20210301', '20210302']
因为1月4号到1月9号,无法继续采用通配符,所以全部枚举;1月10号到1月19号、1月11号到19号、1月21号到1月29号、1月30号到1月31号,均可以用通配符。

将以上问题抽象为数学问题是,给定一个函数,输入的是2个字符串[start,end]的日期范围,输出一个字符串数组,这个字符串数组是给定日期范围的通配符表示式的最简结果

具体的解法为递归,在给定日期范围种,先判断年,如果年不相同,则将中间的年份抽出来,前后两端分别判单,则成为了递归

20200101       20200101-20201231
	    =》     2021
20221231       20220101-20221231     

中间的日期通过通配符表示,前后两端继续递归,直到最后的日期

def function(start: str, end: str):
    def _yyyyMM2dd(yyyy, MM):
        if MM in {1, 3, 5, 7, 8, 10, 12}:
            return 31
        if MM != 2:
            return 30
        if (yyyy % 4 == 0) and (yyyy % 100 != 0) or (yyyy % 400) == 0:
            return 29
        else:
            return 28

    if start == end: return [start]
    if start > end: return []
    res = []
    if start[:4] != end[:4]:  # 年不相同,中间的年份全部用通配符
        for i in range(int(start[:4]) + 1, int(end[:4])):
            res.append("{:0>4}*".format(i))
        res.extend(function(start, f"{start[:4]}1231"))
        res.extend(function(f"{end[:4]}0101", end))
        return res
    if start[4:6] != end[4:6]:  # 月份不一样
        for i in range(int(start[4:6]) + 1, int(end[4:6])):
            res.append("{}{:0>2}*".format(start[:4], i))
        res.extend(function(start, f"{start[:6]}{_yyyyMM2dd(int(start[:4]), int(start[4:6]))}"))
        res.extend(function(f"{end[:6]}01", end))
        if len(res)==12 and len(list(set([i[4:6] for i in res]))) == 12:
            res = ["{}*".format(start[:4])]
        return res
    if start[6:8] != end[6:8]:  # 日期不同
        if start[6] != end[6]:
            for i in range(int(start[6]) + 1, int(end[6])):
                res.append("{}{}*".format(start[:6], i))

            if start[6] in ["0", "1"]:
                start_day_last_num = 9
            elif start[6] == "2":
                if _yyyyMM2dd(int(start[:4]), int(start[4:6])) == 28:
                    start_day_last_num = 8
                else:
                    start_day_last_num = 9
            elif start[6] == "3":
                start_day_last_num = 1
            res.extend(function(start, f"{start[:7]}{start_day_last_num}"))
            if end[6] == "0":
                end_day_first_num = 1
            else:
                end_day_first_num = 0
            res.extend(function(f"{end[:7]}{end_day_first_num}", end))

            # print(res)
            if int(start[4:6]) == 2:
                if len(res)==3 and len(list(set([i[6] for i in res]))) == 3:
                    res = ["{}*".format(start[:6])]
            else:
                if len(res)==4 and len(list(set([i[6] for i in res]))) == 4:
                    res = ["{}*".format(start[:6])]
            # print(res)
            # print()
            return res
        if start[7] != end[7]:
            for i in range(int(start[7]), int(end[7]) + 1):
                res.append("{}{}".format(start[:7], i))
            # 剪枝合并
            # print(res)
            if int(start[4:6]) in [1, 3, 5, 7, 8, 10, 12]:
                if (start[6] == "0" and len(res) == 9) or (start[6] in ["1", "2"] and len(res) == 10) or (
                        start[6] == "3" and len(res) == 2):
                    res = ["{}*".format(start[:7])]
            elif int(start[4:6]) == 2:
                if _yyyyMM2dd(int(start[:4]), int(start[4:6])) == 29:
                    if (start[6] == "0" and len(res) == 9) or (start[6] in ["1", "2"] and len(res) == 10):
                        res = ["{}*".format(start[:7])]
                else:
                    if (start[6] == "0" and len(res) == 9) or (start[6] == "1" and len(res) == 10) or (
                            start[6] == "2" and len(res) == 9):
                        res = ["{}*".format(start[:7])]

            else:
                if (start[6] == "0" and len(res) == 9) or (start[6] in ["1", "2"] and len(res) == 10) or (
                        start[6] == "3" and len(res) == 1):
                    res = ["{}*".format(start[:7])]
            # print(res)
            # print()
            return res


res = function("20201227", "20210302")
res.sort()
print(res)


function("20210101", "20210331") => ['202101*', '202102*', '202103*']
function("20210101", "20211231") => ['2021*']
function("20200101", "20211231") => ['2020*', '2021*']
function("20200104", "20210302") => ['20200104', '20200105', '20200106', '20200107', '20200108', '20200109', '2020011*', '2020012*', '2020013*', '202002*', '202003*', '202004*', '202005*', '202006*', '202007*', '202008*', '202009*', '202010*', '202011*', '202012*', '202101*', '202102*', '20210301', '20210302']
function("20210104", "20210302") => ['20210104', '20210105', '20210106', '20210107', '20210108', '20210109', '2021011*', '2021012*', '2021013*', '202102*', '20210301', '20210302']

  Python知识库 最新文章
Python中String模块
【Python】 14-CVS文件操作
python的panda库读写文件
使用Nordic的nrf52840实现蓝牙DFU过程
【Python学习记录】numpy数组用法整理
Python学习笔记
python字符串和列表
python如何从txt文件中解析出有效的数据
Python编程从入门到实践自学/3.1-3.2
python变量
上一篇文章      下一篇文章      查看所有文章
加:2022-04-09 18:19:02  更:2022-04-09 18:20:39 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 18:32:19-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码