代码之家  ›  专栏  ›  技术社区  ›  blue_note

python dateutil.parser错误(?)解析

  •  2
  • blue_note  · 技术社区  · 7 年前

    我正在尝试以下操作(python 3.6)

    import dateutil.parser as dp
    t1 = '0001-04-23T02:25:43.511Z'
    t2 = '0001-04-23T01:25:43.511Z'
    print(dp.parse(t1))
    print(dp.parse(t2))
    

    这给了我

    0001-04-23 02:25:43.511000+00:00
    0023-01-04 01:25:43.511000+00:00
    

    在各种类似的情况下,当年份字符串具有 00XY 还有时间线 XY ,解析器似乎产生了错误的输出。我是不是漏掉了什么,还是这是个虫子?

    2 回复  |  直到 7 年前
        1
  •  1
  •   Paul    7 年前

    这个 was a bug 在里面 dateutil 那是固定的(最初的工作 here ,但这个特定的边缘案例是固定的 here )使用 python-dateutil>=2.7.0 会解决你的问题。

    import dateutil
    import dateutil.parser as dp
    
    print(dateutil.__version__)
    # 2.7.2
    
    t1 = '0001-04-23T02:25:43.511Z'
    t2 = '0001-04-23T01:25:43.511Z'
    
    print(dp.parse(t1))
    0001-04-23 02:25:43.511000+00:00
    
    print(dp.parse(t2))
    0001-04-23 01:25:43.511000+00:00
    

    我不建议使用 yearfirst 因为它对DateTime字符串的解析方式有其他影响,而且它本质上是一个实现细节,在有缺陷的情况下(因为该缺陷涉及解释 0001 相当于 01 ,但事实并非如此)。

    如果你 知道你有一个ISO-8601格式的日期时间, dateutil.parser.isoparse 会更快更严格,而且没有这个bug。它也在2.7.0版中引入:

    print(isoparse('0001-04-23T02:25:43.511Z'))
    # 0001-04-23 02:25:43.511000+00:00
    
    print(isoparse('0001-04-23T01:25:43.511Z'))
    # 0001-04-23 01:25:43.511000+00:00
    
        2
  •  1
  •   DeepSpace    7 年前

    你应该使用 yearfirst 争论。从 docs :

    YearFirst——是否以模糊的方式解释第一个值 3-整数日期(例如01/05/09)作为年份。如果为真,则第一个数字 取年,否则取最后一个数字 年。如果设置为“无”,则从当前 parserinfo对象(它本身默认为false)。

    import dateutil.parser as dp
    
    t = '0001-04-23T01:25:43.511Z'
    print(dp.parse(t, yearfirst=True))
    # 0001-04-23 01:25:43.511000+00:00