gpt4 book ai didi

python - dateutil.parser 解析 "%Y:%m:%d"格式的日期时出现奇怪的结果

转载 作者:行者123 更新时间:2023-12-03 08:03:49 26 4
gpt4 key购买 nike

我喜欢 dateutil.parser 并经常使用它,因此我不必担心日期时间格式不一致,而且在大多数情况下它对我来说非常可靠。

但是今天我花了一个小时调试试图理解为什么我在数据库中填充的日期都是 2022 年。日期格式为:2009:05:03 08:12:37 存储在照片元数据中并使用 exif 包提取。

感觉它应该是一种相当简单的解析格式,但这就是我分别使用 dateutildatetime 模块得到的:

from dateutil.parser import parse
import datetime as dt

date_string = '2009:05:03 08:12:37'

wrong = parse(date_string, fuzzy=True)
correct = dt.datetime.strptime(date_string, "%Y:%m:%d %H:%M:%S")

print(wrong)
print(correct)

Out:
2022-07-25 08:12:37
2009-05-03 08:12:37

正常解析和模糊解析都给出相同的结果。很奇怪,我什至不明白它是如何得出这个精确结果的。

它看起来尝试解析并成功完成时间,但无法解析日期并默认设置当前日期。这感觉像是一种非常危险的行为。它应该引发异常。

最佳答案

dateutil.parser.parse参数默认说:

The default datetime object, if this is a datetime object and not None, elements specified in timestr replace elements in the default object.

the parser.parse() code on Github 中说得很清楚:

        if default is None:
default = datetime.datetime.now().replace(hour=0, minute=0,
second=0, microsecond=0)

但是记录的行为并没有表明这一点,我同意你的观点,即结果令人惊讶。

至于为什么失败,稍后会_timelex.split(timestr)最终调用 _timelex.get_token() 。它是一个用纯 Python 实现的状态机,用于解析时间字符串,它正确返回标记 ['2009', ':', '05', ':', '03', ' ', '08' , ':', '12', ':', '37']
但随后 _parse() 迭代它们并尝试解释它们,因此它调用 _parse_numeric_token()在上面。此函数尝试将标记与特定情况进行匹配。在某些情况下,“ymd”(年/月/日)被设置(您想要的):

  • YYMMDD(第一个没有任何空格或点的标记 (.))
  • YYYYMMDD[HHMM[ss]](第一个不带空格的标记,包括时间)
  • token 后跟 -/. 之一
  • 最后一个标记或后跟任何 .,;-/' (或 at/on/and/ad/m/t/of/st/nd/rd 的任何单词/th)
  • token 可以是一天

而是匹配“后跟 :”的大小写,然后将其解释为 HH:MM:SS_result(hour=2009, 分钟= 5、秒=3、微秒=0)。它消耗了前 5 个代币(整个预期的 YMD)。之后,它会跳过空格,返回到 _parse_numeric_token(),匹配完全相同的大小写,并将 HMS 覆盖为 _result(hour=8, 分钟=12, Second=37, microsecond =0)
它没有找到任何 YMD,因此 ymd.resolve_ymd() 没有执行任何操作。

返回到parse()(不带前导下划线),它 builds a naive日期时间(无时区),将 parse() 结果字段替换为 default,最终成为最终结果。

我认为这可能是打开issue on GitHub的原因但我担心它可能会被认为是“不会修复”,因为您提供的数据很奇怪:时间部分通常由冒号分隔,而日期部分(基本上)永远不会由它们分隔(参见 ISO 8601 )。我以前从未见过这种日期时间格式。

我建议您要么修复生成此格式错误的数据的代码,要么添加类似 if malformed := re.match("(\d)+:(\d+):(\d+) (\d+:\d+:\d+)", date_string): date_string = f"{malformed.group(0)}-{malformed.group(1)}-{malformed.group(2)} {格式错误。组(3)}"以 dateutil 解析器期望的格式重新格式化数据。


关于fuzzy  :

Whether to allow fuzzy parsing, allowing for string like “Today is January 1, 2047 at 8:21:00AM”.

它实际上做的是在_parse()函数中,它尝试找到当前 token 的匹配项,如果没有匹配,它不会引发ValueError 如果模糊。因此,对于任何有效的非模糊输入,模糊结果将是相同的。
在这种情况下,它不会改变任何内容(但它可能对您收到的其他 date_strings 有用,我不知道)。

关于python - dateutil.parser 解析 "%Y:%m:%d"格式的日期时出现奇怪的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73104677/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com