40

我有一个包含大部分正确日期时间的数据库,但有一些数据库像这样坏了:Sat Dec 22 12:34:08 PST 20102015

没有无效的年份,这对我有用:

end_date = soup('tr')[4].contents[1].renderContents()
end_date = time.strptime(end_date,"%a %b %d %H:%M:%S %Z %Y")
end_date = datetime.fromtimestamp(time.mktime(end_date))

但是一旦我用无效的年份击中了一个对象,我就会得到ValueError: unconverted data remains: 2,这很好,但我不确定如何最好地去除一年中的坏字符。它们的范围从 2 到 6 unconverted characters

任何指针?我只想切片end_date,但我希望有一个日期时间安全的策略。

4

5 回答 5

27

除非你想重写strptime(一个非常糟糕的主意),否则你唯一真正的选择是end_date在最后切掉多余的字符,假设这会给你想要的正确结果。

例如,您可以捕获ValueError、切片并重试:

def parse_prefix(line, fmt):
    try:
        t = time.strptime(line, fmt)
    except ValueError as v:
        if len(v.args) > 0 and v.args[0].startswith('unconverted data remains: '):
            line = line[:-(len(v.args[0]) - 26)]
            t = time.strptime(line, fmt)
        else:
            raise
    return t

例如:

parse_prefix(
    '2015-10-15 11:33:20.738 45162 INFO core.api.wsgi yadda yadda.',
    '%Y-%m-%d %H:%M:%S'
) # -> time.struct_time(tm_year=2015, tm_mon=10, tm_mday=15, tm_hour=11, tm_min=33, ...
于 2011-02-18T18:56:27.443 回答
23

是的,我只是砍掉多余的数字。假设它们总是附加到日期字符串,那么这样的事情会起作用:

end_date = end_date.split(" ")
end_date[-1] = end_date[-1][:4]
end_date = " ".join(end_date)

我打算尝试从异常中获取多余的位数,但是在我安装的 Python 版本(2.6.6 和 3.1.2)上,该信息实际上并不存在;它只是说数据与格式不匹配。当然,您可以继续一次删除一个数字并重新解析,直到没有异常为止。

您还可以编写一个仅匹配有效日期的正则表达式,包括年份中正确的位数,但这似乎有点矫枉过正。

于 2011-02-18T18:57:11.657 回答
6

改进(我希望)Adam Rosenfield 的代码:

import time

for end_date in ( 'Fri Feb 18 20:41:47 Paris, Madrid 2011',
                  'Fri Feb 18 20:41:47 Paris, Madrid 20112015'):

    print end_date

    fmt = "%a %b %d %H:%M:%S %Z %Y"
    try:
        end_date = time.strptime(end_date, fmt)
    except ValueError, v:
        ulr = len(v.args[0].partition('unconverted data remains: ')[2])
        if ulr:
            end_date = time.strptime(end_date[:-ulr], fmt)
        else:
            raise v

    print end_date,'\n'
于 2011-02-18T19:45:55.770 回答
6

这是我使用的更简单的单线:

end_date = end_date[:-4]

于 2018-09-06T21:20:55.820 回答
0

strptime()真的希望看到格式正确的日期,因此您可能需要end_date在调用它之前对字符串进行一些修改。

这是将最后一项切成end_date4 个字符的一种方法:

chop = len(end_date.split()[-1]) - 4
end_date = end_date[:-chop]
于 2011-02-18T18:59:21.850 回答