Python dateutils默认为识别零件的最后一次出现,而不是下一次

Python dateutils默认为识别零件的最后一次出现,而不是下一次,python,datetime,date-parsing,python-dateutil,Python,Datetime,Date Parsing,Python Dateutil,我正在使用解析可能包含部分信息的日期字符串。如果某些信息不存在,parse可以采用一个default关键字参数,它将从中填充任何缺少的字段。此默认值默认为datetime.datetime.today() 对于像dateutil.parser.parse(“星期四”)这样的情况,这意味着它将返回下一个星期四的日期。但是,我需要它返回上一个星期四的日期(包括今天,如果今天恰好是星期四) 因此,假设today==datetime.datetime(2018,2,20)(一个星期二),我希望所有这些a

我正在使用解析可能包含部分信息的日期字符串。如果某些信息不存在,
parse
可以采用一个
default
关键字参数,它将从中填充任何缺少的字段。此默认值默认为
datetime.datetime.today()

对于像
dateutil.parser.parse(“星期四”)
这样的情况,这意味着它将返回下一个星期四的日期。但是,我需要它返回上一个星期四的日期(包括今天,如果今天恰好是星期四)

因此,假设
today==datetime.datetime(2018,2,20)
(一个星期二),我希望所有这些
assert
s都是真的:

from dateutil import parser
from datetime import datetime

def parse(date_str, default=None):
    # this needs to be modified
    return parser.parse(date_str, default=default)

today = datetime(2018, 2, 20)

assert parse("Tuesday", default=today) == today    # True
assert parse("Thursday", default=today) == datetime(2018, 2, 15)    # False
assert parse("Jan 31", default=today) == datetime(2018, 1, 31)    # True
assert parse("December 10", default=today) == datetime(2017, 12, 10)    # False
有没有一个简单的方法来实现这一点?使用当前的
parse
函数,只有第一个和第三个
assert
会通过。

这是您修改过的代码(code.py):

#/usr/bin/env蟒蛇3
导入系统
从dateutil导入解析器
从datetime导入datetime,timedelta
今天=日期时间(2018年2月20日)
数据=[
(“星期二”,今天,今天),
(“星期四”,日期时间(2018年2月15日),今天),
(“1月31日”,日期时间(2018年1月31日),今天),
(“12月10日”,日期时间(2017年12月10日),今天),
]
def parse(date_str,默认值=None):
#这需要修改
返回parser.parse(date\u str,default=default)
定义年内天数(年):
尝试:
日期时间(年,2,29)
除值错误外:
返回365
返回366
def parse2(日期,默认值=无):
dt=parser.parse(date\u str,default=default)
如果默认值不是无:
weekday_strs=[day_str.lower()表示parser.parserinfo中的day_元组。day_str的weekday表示day_元组中的day_str]
如果date_str.lower()在工作日:
如果dt.weekday()>默认值.weekday():
dt-=时间增量(天数=7)
其他:
如果(dt.month>今日.month)或((dt.month==今日.month)和(dt.day>今日.day)):
dt-=时间增量(天数=\年内天数(dt年))
返回dt
def打印统计(解析函数):
打印(“\n打印\“{:s}\”的统计信息。格式(解析函数名)
对于三重输入数据:
d=parse_func(三元组[0],默认值为三元组[2])
打印(“[{:s}][{:s}][{:s}][{:s}][{:s}]”。格式(三重[0],str(d),str(三重[1]),如果d==三重[1]则为“真”,否则为“假”))
如果名称=“\uuuuu main\uuuuuuuu”:
打印(“Python{:s}on{:s}\n.”格式(sys.version,sys.platform))
打印统计数据(解析)
打印统计数据(第2部分)
注释

  • 我“稍微”更改了代码的结构,以将其参数化,因此,如果需要更改(例如,添加一个新的示例),更改应该是最小的
    • 我添加了一个函数(print_stats)来打印结果,而不是断言(如果不匹配,则引发AssertError并退出程序)
      • 获取一个参数(parse_func),该参数是执行解析(例如parse)的函数
      • 将一些全局声明的数据(data)与(上述)函数一起使用
    • 数据-是三元组列表,其中每个三元组包含:
    • 要转换的文本
    • 转换生成的预期日期时间()
    • 传递给解析函数(parse_func)的默认参数
  • parse2函数(parse的改进版本):

    • 接受两种类型的日期字符串:
    • 工作日名称
    • 月/日(无序)
    • 执行常规解析,如果转换的对象位于作为默认参数传递的对象之后(通过比较两个对象的相应属性确定),则会减去一个句点(请查看):
    • “星期四”在“星期二”之后,所以它减去一周的天数(7)
    • “12月10日”在“2月20日”之后,因此它减去一年中的天数*
    • 工作日:我最好举例说明:

      >parser.parserinfo.WEEKDAYS
      [(“周一”、“周一”)、(“周二”、“周二”)、(“周三”、“周三”)、(“周四”、“周四”)、(“周五”、“周五”)、(“周六”、“周六”)、(“太阳”、“周日”)]
      >>>[day_str.lower()表示parser.parserinfo中的day_元组。day_str在day_元组中的工作日]
      [‘星期一’、‘星期二’、‘星期三’、‘星期四’、‘星期五’、‘星期六’、‘星期二’、‘星期三’、‘星期四’、‘星期五’、‘星期六’、‘星期日’]
      
      • 平展
        parser.parserinfo.WEEKDAYS
      • 将字符串转换为小写(用于简化比较)
  • _年天数*-正如您可能猜到的,返回一年中的天数(不能简单地减去365,因为闰年可能会把事情搞砸): dt=datetime(2018,3,1) >>>dt datetime.datetime(2018,3,1,0,0) >>>dt-时间增量(365) datetime.datetime(2017,3,1,0,0) >>>dt=日期时间(2016,3,1) >>>dt datetime.datetime(2016,3,1,0,0) >>>dt-时间增量(365) datetime.datetime(2015,3,2,0,0)
输出

(py35x64_测试)E:\Work\Dev\StackOverflow\q048884480>“E:\Work\Dev\VEnvs\py35x64_测试\Scripts\python.exe”code.py
win32上的Python 3.5.4(v3.5.4:3f56838,2017年8月8日,02:17:05)[MSC v.1900 64位(AMD64)]
打印“解析”的统计信息
[星期二][2018-02-20 00:00:00][2018-02-20 00:00:00][真实]
[周四][2018-02-22 00:00:00][2018-02-15 00:00:00][假]
[1月31日][2018-01-31 00:00:00][2018-01-31 00:00:00][真实]
[12月10日][2018-12-10 00:00:00][2017-12-10 00:00:00][假]
正在打印“parse2”的统计信息
[星期二][2018-02-20 00:00:00][2018-02-20 00:00:00][真实]
[星期四][2018-02-15 00:00:00][2018-02-15 00:00:00][真实]
[1月31日][2018-01-31 00:00:00][2018-01-31 00:00:00][真实]
[12月10日][2017-12-10 00:00:00][2017-12-10 00:00:00][真实]
以下是您修改的代码(code.py):

#/usr/bin/env蟒蛇3
导入系统
从dateutil导入解析器
从datetime导入datetime,timedelta
今天=日期时间(2