基于时间区间取天数的小算法

哈喽,大家好呀,好久不见!因为最近太忙了,就一直忘了更新文章。不过今天,就大家分享一期小算法(哈哈,就是简单的逻辑规则罢了)

最近在工作期间,需求提出了一个之前没有遇到过的问题,就是有一个需求字段是日期天数,但是原网站给出的是一个时间区间,而且我们都知道,做数据聚合的时候,就会出现各种情况,同样,聚合的数据有各种形式的时间区间,如2017年12月26日至2016年7月6日、2016-04-20至2016-06-30、5个月、22016.10.1-2016.11.16 47天、201908-202106等等情况。那么我们要将这些数据转换成天数,就可以考虑写一个小的训练算法,我们就可以写规则去匹配各种形式的时间区间文本

1.首先,先介绍一下我们要用到的包,这里主要是用到的是pandas,大家都知道,数据处理分析方面pandas是有着强大的优势的。另外就是需要用到cn2an,在这里我是用它来将 ‘五个月’ 类似的格式的月数转数字,方便进行后续操作

import datetime, cn2an
import re
import pandas as pd

def cn_to_an(text):
    output = cn2an.cn2an(text, "smart")
    return output

 2.第二步就是将时间区间文本进行前、后时间点进行分离(这里的规则大家可以按自己需求完善)

def get_date_difference(date_str):
    if '至' in date_str:
        date_before = date_str.split('至')[-1]
        date_after = date_str.split('至')[0]
        days = 0
    elif '-' in date_str and '天' in date_str and ',' not in date_str and ',' not in date_str:
        date_before = ''
        date_after = ''
        days = date_str.split(' ')[-1].replace('天', '').strip()
    elif '-' in date_str and ',' in date_str:
        date_before = ''
        date_after = ''
        days = date_str.split(',')[-1].replace('天', '').strip()
    elif '-' in date_str and ',' in date_str:
        date_before = ''
        date_after = ''
        days = date_str.split(',')[-1].replace('天', '').strip()
    elif '-' in date_str and '天' not in date_str and ',' not in date_str and ',' not in date_str and '.' not in date_str:
        date_before0 = date_str.split('-')[-1]
        if len(date_before0) == 8:
            date_before = date_str.split('-')[-1][:4] + '.' + date_str.split('-')[-1][4:6] + '.' + date_str.split('-')[-1][6:]
            date_after = date_str.split('-')[0][:4] + '.' + date_str.split('-')[0][4:6] + '.' + date_str.split('-')[0][6:]
            days = 0
        elif len(date_before0) == 6:
            date_before = date_str.split('-')[-1][:4] + '.' + date_str.split('-')[-1][4:]
            date_after = date_str.split('-')[0][:4] + '.' + date_str.split('-')[0][4:]
            days = 0
        else:
            date_before = ''
            date_after = ''
            days = '0'
    elif '-' in date_str:
        date_before = date_str.split('-')[-1]
        date_after = date_str.split('-')[0]
        days = 0
    elif '-' in date_str and '天' in date_str:
        date_before = ''
        date_after = ''
        days = date_str.split(' ')[-1].replace('天', '').strip()
    elif '-' in date_str:
        date_before = date_str.split('-')[-1]
        date_after = date_str.split('-')[0]
        days = 0
    elif '—' in date_str and '天' in date_str:
        date_before = ''
        date_after = ''
        days = date_str.split(' ')[-1].replace('天', '').strip()
    elif '—' in date_str and '工期' in date_str:
        date_before = ''
        date_after = ''
        days = date_str.split(' ')[-1].replace('工期', '').strip()
    elif '—' in date_str:
        date_before = date_str.split('—')[-1]
        date_after = date_str.split('—')[0]
        days = 0
    elif '~' in date_str and '天' in date_str:
        date_before = ''
        date_after = ''
        days = date_str.split(' ')[-1].replace('天', '').strip()
    elif '~' in date_str:
        date_before = date_str.split('~')[-1]
        date_after = date_str.split('~')[0]
        days = 0
    elif '——' in date_str and '天' in date_str:
        date_before = ''
        date_after = ''
        days = date_str.split(' ')[-1].replace('天', '').strip()
    elif '——' in date_str:
        date_before = date_str.split('——')[-1]
        date_after = date_str.split('——')[0]
        days = 0
    elif '天' in date_str and '-' not in date_str and '至' not in date_str:
        date_before = ''
        date_after = ''
        days = date_str.replace('(日历天)', '').replace('日历天', '').replace('天', '').strip()
    elif "个月" in date_str:
        date_before = ''
        date_after = ''
        days0 = "" if re.search('(.*)个月', date_str, re.S) == None else re.search('(.*)个月', date_str, re.S).group(1).strip()
        days = "" if days0 == '' else str('%.0f' % (cn_to_an(days0)*30))
    elif '天' not in date_str and '-' not in date_str and '至' not in date_str:
        date_before = ''
        date_after = ''
        days = date_str.strip()
    else:
        date_before = ''
        date_after = ''
        days = date_str.strip()
    return date_before, date_after, days

 3.第三步就是将各种格式的时间字符串转时间格式(这里的规则大家可以按自己需求去完善)

def to_datetime_str(time_str):
    new_time = pd.to_datetime(time_str, yearfirst=True, errors='ignore')
    if new_time == time_str:
        # 特殊格式的时间,可以再这里添加规则
        format_list = ["%Y~%m~%d", "%Y|%m|%d", "%Y~%m~%d %H:%M:%S", "%Y|%m|%d %H:%M:%S", "%Y年%m月%d日"]
        format_index = 0
        while new_time == time_str:
            if format_index == len(format_list):
                return {"succ": False, "datetime": None, "datetime_string": "没有匹配当前时间的规则"}
            new_time = pd.to_datetime(time_str, format=format_list[format_index], yearfirst=True, errors='ignore')
            if new_time != time_str:
                return {"succ": True, "datetime": new_time.to_pydatetime(), "datetime_string": str(new_time)}
            format_index += 1
    else:
        return {"succ": True, "datetime": new_time.to_pydatetime(), "datetime_string": str(new_time)}

4.第四步就是获取前后日期的差值天数 

def date_difference(date_before, date_after):
    date_before = datetime.datetime.strptime(date_before, '%Y-%m-%d %H:%M:%S')
    date_after = datetime.datetime.strptime(date_after, '%Y-%m-%d %H:%M:%S')
    days = date_after - date_before
    return days.days

5.最后,通过函数调用以上方法,实现各种时间区间的天数转换 

def get_days(date_text):
    a = get_date_difference(date_text)[0]
    b = get_date_difference(date_text)[1]
    c = get_date_difference(date_text)[2]
    # print(a, b, c)
    if a == '' or b == '':
        days = c.replace('日', '')
    else:
        date_before = to_datetime_str(b)
        date_after = to_datetime_str(a)
        if date_after.get('succ') and date_before.get('succ'):
            date_before = date_before.get('datetime_string')
            date_after = date_after.get('datetime_string')
            days = str(date_difference(date_before, date_after)).replace('-', '')
        else:
            days = '0'
    return days

展示结果: 

    print('********************')
    print(get_days('2017年12月26日至2016年7月6日'))
    print(get_days('2016-04-20至2016-06-30'))
    print(get_days('5个月'))
    print(get_days('230 天'))
    print(get_days('480(日历天)'))
    print(get_days('480 日历天'))
    print(get_days('2017.2.20-2018.6.30'))
    print(get_days('2017.4-2017.9'))
    print(get_days('2017.04-2017.12'))
    print(get_days('22016.10.1-2016.11.16 47天'))
    print(get_days('2016/10/01-2017/10/01'))
    print(get_days('1900-01-01至1900-01-01'))
    # '2019.05.29-2020.12.31、'
    print(get_days('2019.05.29-2020.12.31'))
    # '2019.02.11~2019.08.10、'
    print(get_days('2019.02.11~2019.08.10'))
    # '2017.7.1——2018.12.31、'
    print(get_days('2017.7.1——2018.12.31'))
    # '2016.4.20-2016.12.31,251(逗号后面的是天数)、'
    print(get_days('2016.4.20-2016.12.31,251天'))
    # '2016.12.01-2017.06.06,203(逗号后面的是天数)、'
    print(get_days('2016.12.01-2017.06.06,203天'))
    # '2014.5—2014.8(按月初算)、'
    print(get_days('2014.5—2014.8'))
    # '2016.10.9—2017.1.6 工期90'
    print(get_days('2016.10.9—2017.1.6 工期90'))
    # '5.0(五个月)、'
    print(get_days('5个月'))
    # 660日
    print(get_days('660日'))
    # 2014.05.20-2014.11.31
    print(get_days('2014.05.20-2014.11.30'))
    # 201908-202106
    print(get_days('2019.08-2021.06'))
    print(get_days('201908-202106'))
    print(get_days('20170305-20171005'))

那么本期的分享就结束了,想要学习更多的python爬虫相关技巧和知识的小伙伴们一定要点下关注哟,后期会不定时分享相关干货内容。临近年底,最后祝大家春节快乐,事业兔飞猛进!!!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Crazy ProMonkey

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值