jtyoui.time.parsetime 源代码

#!/usr/bin/python3.7
# -*- coding: utf-8 -*-
# @Time  : 2019/10/31 13:21
# @Author: Jtyoui@qq.com
from jtyoui.data import reader_conf
import time
import configparser
import os
import datetime
import re

NOW_TIME = time.localtime(time.time())


[文档]class ParseTime: def __init__(self, data, current_date=None, date_format='%Y-%m-%d %H:%M:%S', **kwargs): """初始化数据日期 :param data: 当前数据 :param current_date: 当前日期 :param date_format: 日期解析格式 :param kwargs: 其他参数 - map_path: 解析日期的映射表 - re_path: 匹配日期的正则表 """ # 加载日期的映射表和匹配日期的正则表 self.map, self.re = None, None self.load_config(**kwargs) self.data = data + '\033' self._decide_ten() # 定义当前日期 self.localtime = current_date if current_date else time.strftime(date_format) self.format = date_format # 将当前日期标准化 local = time.strptime(self.localtime, self.format) # 初始化当前的年月日基本信息 self.now_year = local.tm_year self.now_mon = local.tm_mon self.now_day = local.tm_mday self.now_week = local.tm_wday + 1 if current_date: self.now_hour = local.tm_hour self.now_minute = local.tm_min self.now_second = local.tm_sec else: self.now_hour = 0 self.now_minute = 0 self.now_second = 0 self.reduction = True # 启动还原时分秒
[文档] def load_config(self, map_path=None, re_path=None): """自定义日期解析映射表和匹配日期的正则表 :param map_path: 解析日期的映射表 :param re_path: 匹配日期的正则表 """ path = os.path.dirname(__file__) self.map = configparser.ConfigParser() if map_path: self.map.read(map_path, encoding='UTF-8') else: self.map.read(path + os.sep + 'map.ini', encoding='UTF-8') if re_path: self.re = reader_conf(re_path) else: self.re = reader_conf(path + os.sep + 're.cfg')
[文档] def change_time(self, day=0, hour=0, minute=0, week=0, second=0): """增加天数来修改时间""" add_time = datetime.timedelta(days=day, hours=hour, minutes=minute, weeks=week, seconds=second) if self.reduction: change = F'{self.now_year}-{self.now_mon}-{self.now_day} 00:00:00' # 时分秒还原到0 self.reduction = False else: change = self.str_time() add = datetime.datetime.strptime(change, self.format) + add_time self.now_year = add.year self.now_mon = add.month self.now_day = add.day self.now_hour = add.hour self.now_minute = add.minute self.now_second = add.second self.now_week = add.isoweekday()
def _analysis(self, name): """分析数据获取年月日周时分秒中的有效信息 :param name: 年月日时周分秒调用名字 :return: 改变的值 """ re_year = '|'.join(self.re['re_' + name]) ls = re.search(re_year, self.data) if ls is not None: message = ls.group() add_year = self.map['add_' + name] value = add_year.get(message, 0) else: value = 0 return int(value)
[文档] def standard_time(self): """标准时间化""" return time.strptime(self.str_time(), self.format)
[文档] def str_time(self): """字符串时间""" return self.__str__()
[文档] def day(self): """查询天数""" value = self._analysis('day') if value == 0: re_year = '|'.join(self.re['re_day']) change_day = re.search(re_year, self.data) if change_day: message = change_day.group() if message[:-1].isdigit(): self.now_day = message[:-1] elif '后' in message: value = int(message[:message.find('天')]) elif '前' in message: value = -int(message[:message.find('天')]) self.change_time(day=value)
[文档] def month(self): """查询月份""" value = self._analysis('month') if value == 0: re_month = '|'.join(self.re['re_month']) change_month = re.search(re_month, self.data) if change_month: message = change_month.group() if '个月' in message: point = message[:message.find('个')] else: point = message[:message.find('月')] if point.isdigit(): point = int(point) if '底' in message: self.now_mon = point + 1 self.now_day = 1 self.change_time(day=-1) elif '除' in message: self.now_mon = point self.now_day = 1 elif '后' in message: value = point elif '前' in message: value = -point else: self.now_mon = point if value: mon = self.now_mon + value if mon == 0: self.now_year -= 1 mon = 12 if mon > 12: over_12_mon, mod_12 = divmod(mon, 12) self.now_year += over_12_mon self.now_mon = mod_12 else: self.now_mon = mon
[文档] def year(self): """查询年份""" value = self._analysis('year') if value == 0: re_year = '|'.join(self.re['re_year']) change_year = re.search(re_year, self.data) if change_year: message = change_year.group() if message[:-1].isdigit(): self.now_year = int(message[:-1]) else: self.now_year += value
[文档] def week(self): """查找第几个周""" value = self._analysis('week') self.change_time(week=value)
[文档] def what_week(self): """查找当前周中的第几个星期""" ds = self.map['chinese_number'] keys = r'星期(\d+|' + '|'.join(ds.keys())[4:-11] + '天|日)' match = re.search(keys, self.data) if match is not None: value = match.group() point = value[2:] if point.isdigit(): w = int(point) elif ds.get(point, None) is not None: w = int(ds[point]) elif point in '天日': w = 7 else: w = self.now_week # 暂未设置 differ = w - self.now_week self.change_time(day=differ)
[文档] def hour(self): """查找当前的小时""" re_hour = '(' + '|'.join(self.re['re_hour']) + ')' + r'\d+点' match = re.search(re_hour, self.data) if match is not None: value = match.group() add_hour = int(value[2:-1]) point = value[:2] sc = int(self.map['add_hour'].get(point, 0)) if add_hour < sc: if '凌晨' in value and add_hour == 12: add_hour = sc # 凌晨12点等于凌晨0点 else: add_hour += sc self.change_time(hour=add_hour) else: self.reduction = False
[文档] def minute(self): """查找当前的分钟""" re_minute = '|'.join(self.re['re_minute']) match = re.search(re_minute, self.data) if match is not None: value = match.group() if '点半' in value: add_min = 30 elif '分' in value: add_min = int(value[:-1]) else: add_min = 0 # 其他情况 self.change_time(minute=add_min)
[文档] def second(self): """查找当前的秒钟""" re_second = '|'.join(self.re['re_second']) match = re.search(re_second, self.data) if match is not None: value = match.group() if '秒' in value: add_second = int(value[:-1]) self.change_time(second=add_second)
[文档] def parse(self): """开始解析,返回解析后的标准时间""" self.second() self.minute() self.hour() self.week() self.what_week() self.day() self.month() self.year() return self
[文档] def find_times(self): """同StringTime.find_times中的一样""" return [self.parse().__str__()]
def _decide_ten(self): """重新映射一些词语""" chinese_number = self.map['chinese_number'] str_ = list() for data in self.data: if data == '周': # 如果又有周又有星期,不改变 if '星期' in self.data: str_.append(data) else: # 否则将周改为星期 str_.append(self.map['chinese_number'].get(data, data)) elif data != '十' and data in chinese_number: # 十为特殊符号 str_.append(self.map['chinese_number'][data]) else: str_.append(data) if '十' in str_: # 判断十在每个位置上的不同意义 for index, c in enumerate(str_): if c == '十': if str_[index - 1].isdigit() and str_[index + 1].isdigit(): # 比如:二十一实际上十可以取空,变成21 str_[index] = '' elif str_[index - 1].isdigit() and (not str_[index + 1].isdigit()): # 比如:二十实际上十变成0,变成20 str_[index] = '0' elif not str_[index - 1].isdigit() and str_[index + 1].isdigit(): # 比如:十三实际上十变成1,变成13 str_[index] = '1' else: str_[index] = '10' # 其余情况十就变成10 self.data = ''.join(str_[:-1]) def __add__(self, other): """两个时间对象相加""" pass def __mul__(self, other): """两个时间对象相减""" pass def __str__(self): """字符串格式化""" return F'{self.now_year}-{self.now_mon}-{self.now_day} ' \ F'{self.now_hour:0>2}:{self.now_minute:0>2}:{self.now_second:0>2}'
if __name__ == '__main__': today = '2019-10-31 16:00:00' pt = ParseTime('上上个周星期天下午2点25分钟30秒', today).parse() print(pt) # 2019-10-20 14:25:30 print('-----------------切换日期------------------') st = ParseTime('下周星期一下午2点半开会', today).parse() print(st) # 2019-11-4 14:30:00 print('----------------多个时间-------------------') st = ParseTime('今天下午3点', today).parse() print(st) # 2019-10-31 15:00:00 print('----------------没有时间-------------------') st = ParseTime('我要是不传时间呢?', today).parse() print(st) # 2019-10-31 16:00:00 print('---------------只有天数--------------------') st = ParseTime('明天去哪里?', today).parse() print(st) # 2019-11-1 16:00:00 print('---------------没有日期或者天数--------------------') st = ParseTime('下午2点半开会', today).parse() print(st) # 2019-10-31 14:30:00 print('---------------*几个月以后--------------------') st = ParseTime('下个月1号下午3点', today).parse() print(st) # 2019-11-1 15:00:00 print('--------------几天之后--------------') st = ParseTime('三天之前下午3点', today).parse() print(st) # 2019-10-28 15:00:00 print('--------------几月底--------------') st = ParseTime('明年的2月底之前必须交报告', today).parse() print(st) # 2020-2-28 16:00:00 print('--------晚上-----------') st = ParseTime('3月除', today).parse() print(st) # 2019-3-1 16:00:00 print('--------下个周几-----------') st = ParseTime('下个周2', today).parse() print(st) # 2019-11-5 16:00:00 print('--------几个月以后的日期--------') st = ParseTime('5个月后的明天', today).parse() print(st) # 2020-4-1 16:00:00 print('------------凌晨或者半夜------------------') st = ParseTime('昨天凌晨3点', today).parse() print(st) # 2019-10-31 03:00:00 print('-------------只说时间-----------------------') st = ParseTime('二零零七年八月二十一号下午2点半', today).parse() print(st) # 2007-8-21 14:30:00