如何从Python日期时间对象中删除未转换的数据

时间:2011-02-18 18:37:05

标签: python datetime strptime

我有一个大多数正确的日期时间的数据库,但有一些像这样破坏: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,但我希望有一个日期安全策略。

5 个答案:

答案 0 :(得分:16)

是的,我只是砍掉了额外的数字。假设它们总是附加到日期字符串,那么这样的东西就可以了:

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

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

你也可以编写一个只匹配有效日期的正则表达式,包括一年中正确的位数,但这似乎有点过头了。

答案 1 :(得分:14)

除非你想重写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, ...

答案 2 :(得分:5)

改善(我希望)亚当罗森菲尔德的代码:

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'

答案 3 :(得分:1)

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

end_date = end_date[:-4]

答案 4 :(得分:0)

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

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

chop = len(end_date.split()[-1]) - 4
end_date = end_date[:-chop]