我希望“parseutil.parser”字段的 None 值无法解析,而不是默认值

问题描述 投票:0回答:1

我正在尝试使用 parseutil.parser 来解析字符串中的日期。

日期完成后没有问题:

I was born October 11th 2002 -> date(2002, 10, 11)

但是当它是不完整的日期时,parseutil.parser 会尝试用今天的日期“自动填充”它,如下所示:

I need documents from 2003 -> date(2003, 2, 23) (today's month and year)

我想要的是这样的

I need documents from 2003 -> date(2003, None, None)

我尝试将“default=date(None, None, None)”传递给解析器,但日期时间字段不能为 None,因此该解决方案是不可能的。我可以传递一个默认日期,但该日期将在一年中的 1 天有效,因此稍后无法判断它是不完整的解析还是成功的解析。

“为什么需要这样做?”

因为日期不完整我需要将它们变成间隔,所以:

I need documents from 2003 -> date(2003, 1, 1), date(2003, 12, 31)

并且月份和年份匹配的日期也变成间隔但更小:

I need documents from March 2003 -> date(2003, 3, 1), date(2003, 3, 31)

现在我真的无法做到这一点,因为在我调用 parseutil.parser.parse() 之后,我不知道它是完全匹配还是部分匹配,也不知道匹配的字段。

我做了什么

我已经检查了文档,甚至尝试扩展日期类以使其可为空并将其作为默认值传递给解析器,但它不起作用。

python date python-dateutil
1个回答
0
投票

有一种方法可以通过使用

parse()
两次但使用不同的默认日期来实现此目的。

技巧是比较结果日期的年、月、日。 如果它们全部匹配 - 返回任何解析的日期,否则 - 确定并返回间隔。

from dateutil.parser import parse
from datetime import datetime
from calendar import monthrange

DEF_DATE = datetime(1, 1, 1)
DEF_DATE_ALT = datetime(2, 2, 2)

def resolve(date_str):
    dx = parse(default=DEF_DATE, timestr=date_str, fuzzy=True)
    dy = parse(default=DEF_DATE_ALT, timestr=date_str, fuzzy=True)
    is_y = dx.year == dy.year
    is_m = dx.month == dy.month
    is_d = dx.day == dy.day
    if (is_y and is_m and is_d):
        return dx

    start = datetime(dx.year if is_y else 1,
                    dx.month if is_m else 1,
                    dx.day if is_d else 1)
    
    end_y = dx.year if is_y else dx.max.year
    end_m = dx.month if is_m else dx.max.month
    end = datetime(end_y, end_m,
                dx.day if is_d else monthrange(end_y, end_m)[1])
    return (start, end)


print(repr(resolve('I was born October 11th 2002')))
print(repr(resolve('I need documents from 2003')))
print(repr(resolve('I need documents from March 2003')))

输出:

datetime.datetime(2002, 10, 11, 0, 0)
(datetime.datetime(2003, 1, 1, 0, 0), datetime.datetime(2003, 12, 31, 0, 0))
(datetime.datetime(2003, 3, 1, 0, 0), datetime.datetime(2003, 3, 31, 0, 0))

而且无需担心

该日期一年中只有 1 天有效

因为默认日期的所有重要值都彼此不同。

即使这些日期更改为

DEF_DATE = datetime(2024, 2, 23)
DEF_DATE_ALT = datetime(3, 3, 3)

它仍然会产生正确的输出。

© www.soinside.com 2019 - 2024. All rights reserved.