web-dev-qa-db-ja.com

Python datetimeオブジェクトから未変換のデータを削除する方法

私はほとんど正しい日付時刻のデータベースを持っていますが、いくつかはそのように壊れています: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しかし、日時に安全な戦略があることを期待しています。

25
Flowpoke

ええ、私はちょうど余分な数字を切り落とします。それらが常に日付文字列に追加されると仮定すると、次のようになります:

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つずつ数字を切り落とし、再解析を続けることができます。

また、年の正しい桁数を含む有効な日付のみに一致する正規表現を作成することもできますが、それはやり過ぎのようです。

16
kindall

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, ...
15
Adam Rosenfield

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'
5
eyquem

私が使用するさらにシンプルなワンライナーは次のとおりです。

end_date = end_date[:-4]

1
skeller88

strptime()は、正しくフォーマットされた日付を実際に期待しているため、呼び出す前に、おそらくend_date文字列を変更する必要があります。

これは、end_dateの最後の項目を4文字に切り刻む1つの方法です。

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