web-dev-qa-db-ja.com

dateutil.parserを使用したDDMMYYYYの変換

次の文字列入力があります:24052017。私がやろうとすると:

>>>dateutil.parser.parse("24052017")

month must be in 1..12と表示されます。

私もやってみました:

>>>dateutil.parser.parse("24052017", firstday=True)

それは私にまったく同じ結果を与えます。

起こっているように見えるのは、スペースや区切り文字がないという事実が気に入らないということです。日は正しく読みますが、月になると0520と読みます。少なくとも、これは私が疑うことです。

文字列を操作せずに、dateutil.parserを使用してこの特定の入力を変換するにはどうすればよいですか?

7
Renier

この形式は現在、dateutilではサポートされていません。一般に、日付の形式がわかっていてタイムゾーンがない場合は、datetime.datetime.strptimeを使用して日付を解析する必要があります。これは、dateutil.parser.parseにはかなりの量のオーバーヘッドがあるためです。日付の形式を把握してください。重大なことに、その形式が間違っている可能性があります。

この形式を追加するために議論されている2.6.0ブランチに対するプルリクエストがあります。それを見つけることができます ここでは、on dateutilのgithub 。これに対する主な議論は、一連の日付を解析しようとすると、12052017は「2017年12月5日」と解釈されますが、13052017は「2017年5月13日」と解釈されるというものです。 (とはいえ、最初の日付が2017年12月5日まで解析されるという点で、同じ矛盾がありますが、2番目の日付は単に失敗します)。

あなたがそうするならnotは文字列のフォーマットを知らないが、あなたはそれを知っているifこれはDDMMYYYYとして解釈される8桁の数値の日付です。今のところ、最善の策は、その例外をパーサーにハードコーディングすることです。

from dateutil.parser import parse as duparse
from datetime import datetime

def parse(dtstr, *args, **kwargs):
    if len(dtstr) == 8 and dtstr.isnumeric():
        return datetime.strptime(dtstr, '%d%m%Y')
    else:
        return duparse(dtstr, *args, **kwargs)

dateutilに対してより柔軟で拡張可能なパーサーを提供するために、動きの遅い計画された取り組みがいくつかありますが、これについてはまだ多くの作業が行われていません。

8
Paul

dateutilの使用に関心がない場合は、datetime.datetime.strptimeを使用してこれを行うことができます。

from datetime import datetime

print datetime.strptime("24052017", '%d%m%Y')

これは(yyyy-mm-dd hh:mm:ssで)を返します

2017-05-24 00:00:00
7
asongtoruin

さて、_dateutil.parser.parse_には、解析しようとしている日付形式に関するヒントが必要です。このようなヒントがない場合は、YYYYMMDD形式を想定しているため、入力は_2405-20-17_と同等になります。文字列を再配置して_20170524_を読み取るか、たとえばこのdateutil.parser.parse(d[4:8]+d[2:4]+d[0:2])のようにするか、区切り文字を使用します。dateutil.parser.parse("24.05.2017")は機能します(ただし、後者)。

2
Błotosmętek

asongtoruin'answer に記載されているように、datetimeライブラリを使用する必要があります。ただし、_dateutil.parser_を使用してこれを実現する場合は、最初に文字列をdateutilが理解できる形式に変換する必要があります。以下に例を示します。

_>>> d_string = "24052017"

#                                                    to consider day before month v
>>> dateutil.parser.parse('/'.join([d_string[:2], d_string[2:4],d_string[4:]]), dayfirst=True)
datetime.datetime(2017, 5, 24, 0, 0)
_

ここでは、dateutil.parser.parse(...)に渡される前に、_"24052017"_を_"24/05/2017"_に変換しています。

1

dateutil.parser.parseの使用を主張する場合は、次のようにすることをお勧めします。

d = '24052017'
dateutil.parser.parse(d[4:8]+d[2:4]+d[0:2])
1
Błotosmętek