python - dateutil.parser : how to deal with dd/mm and mm/dd in same column?

标签 python validation date python-dateutil

我正在解析一个 CSV 文件,其中一列是“日期时间”。这些 CSV 格式错误,一些 CSV 文件有 28-02-2018T00:00:00.000+1000 而其他 CSV 文件有 2018-02-28T00:00:00.000+1000.

如果我这样做:

dateutil.parser.parse(my_csv["timestamp"])

my_csv["timestamp"]02-28-2018T00:00:00.000+1000 还是 2018-02-28T00:00:00.000+ 1000 无关紧要。如果我不指定格式也是正确的,因为库会识别出没有“28 月”,因此它会自行选择正确的格式。

但是如何处理日期和月份对两个格式槽都有效的情况?

2018-02-0404-02-2018 都是相同的日期,但是一个有 %m-%d 和另一个有 %d-%m

我可以告诉解析器格式是 %y-%m-%d OR %d-%m-%y?

我在解析时是否可以使用其他参数来告诉解析器,如果 %y 的 4 位数字首先出现,则使用 %y-%m-% d 否则使用 %d-%m-%y?

最佳答案

目前 dateutil 解析器的自定义选项很少,无法指定您想要的内容。

但是,如果只是这两种格式,我建议根本不要使用 dateutil 的解析器。您可以使用先尝试一种格式然后再尝试另一种格式的函数来解析这些日期:

from datetime import datetime

def parse_myformats(dtstr):
    try:
        return datetime.strptime(dtstr, '%Y-%m-%dT%H:%M:%S.%f%z')
    except ValueError:
        return datetime.strptime(dtstr, '%d-%m-%YT%H:%M:%S.%f%z')

这假定 Python 3(%z 指令)。在 Python 2 中,您必须去掉最后 5 位数字并单独解析时区。

也就是说,由于第一个日期时间是 ISO8601 日期时间,您还可以使用 dateutil.parser.isoparse作为条件的第一个分支,并使用 parse 作为回退:

from datetime import datetime
from dateutil import parser

def parse_myformats_du(dtstr):
    try:
        return parser.isoparse(dtstr)
    except ValueError:
        return parser.parse(dtstr, dayfirst=True)

此版本无需额外修改即可在 Python 2 和 3 中运行,但在调用 dateutil.parser.parse 的分支上它可能会更慢。查看实际效果:

>>> parse_myformats('2018-02-04T00:00:00.000+1000')
datetime.datetime(2018, 2, 4, 0, 0, tzinfo=datetime.timezone(datetime.timedelta(0, 36000)))

>>> parse_myformats('04-02-2018T00:00:00.000+1000')
datetime.datetime(2018, 2, 4, 0, 0, tzinfo=datetime.timezone(datetime.timedelta(0, 36000)))

>>> parse_myformats_du('2018-02-04T00:00:00.000+1000')
datetime.datetime(2018, 2, 4, 0, 0, tzinfo=tzoffset(None, 36000))

>>> parse_myformats_du('04-02-2018T00:00:00.000+1000')
datetime.datetime(2018, 2, 4, 0, 0, tzinfo=tzoffset(None, 36000))

如果您关心速度,这里是 IPython %timeit 微基准测试:

%timeit parse_myformats('2018-02-04T00:00:00.000+1000')
31.8 µs ± 1.23 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

%timeit parse_myformats('04-02-2018T00:00:00.000+1000')
45.1 µs ± 2.34 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

%timeit parse_myformats_du('2018-02-04T00:00:00.00+1000')
31.3 µs ± 574 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

%timeit parse_myformats_du('04-02-2018T00:00:00.000+1000')
191 µs ± 2.99 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

关于python - dateutil.parser : how to deal with dd/mm and mm/dd in same column?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51100878/

相关文章:

python - 在 tensorflow GPU 中训练卷积神经网络时出现 "Python has stopped Working"

python - 在pygame中添加/创建下拉选择框的技巧

asp.net-mvc - 使用 mvc 4 razor 引擎为 3 个文本框显示一条错误消息

c# - 数据验证 - 哪个更快?

mysql - Mysql根据月份和日期搜索数据

python - 计算行数并对其编号

python - 如何在Python(elementtree)中向musicXML树添加新元素?

java - 良好实践 - Spring 验证 - 前端与后端

R - 使用 ggplot2 在 x 轴上绘制儒略日

javascript - 来自json对象的Angular.js格式日期