2016-12-13 8 views
1

有効なISO-8601日時であれば、文字列を受け取り、Trueを返します。それ以外の場合は、タイムゾーンオフセット-Falseを含むマイクロ秒に正確です。PythonでISO-8601日時文字列を検証しますか?

私は日時文字列を解析のさまざまな方法を提供otherquestionsを発見したが、私は唯一のISO-8601形式の場合にTrueを返したいです。 ISO-8601と一致しないフォーマットでエラーを返すことができない限り、解析は役に立たない。

は(私は私のコードの他の場所で素敵なarrowライブラリを使用しています歓迎されるであろうarrowを使用するソリューションを。。)


EDIT:一般的な解決策は、「この文字列aがすることが表示されます有効なISO 8601 datetime "は一般的なPython日時パッケージには存在しません。

ので、より具体的で釈明、この質問を狭くするために、私はこの形式で日時文字列を検証するフォーマット文字列のために解決されます:

'2016-12-13T21:20:37.593194+00:00' 

現在、私が使用しています:

format_string = '%Y-%m-%dT%H:%M:%S.%f%z' 
datetime.datetime.strptime(my_timestamp, format_string) 

これは与える:

ValueError: time data '2016-12-13T21:20:37.593194+00:00' does not match format '%Y-%m-%dT%H:%M:%S.%f%z' 

問題はのUTCにコロンであるように思えますfset(+00:00)。結局、オフセットをコロン(例えば、'2016-12-13T21:20:37.593194+0000')なしで使用すると、期待どおりに正しく解析されます。これは明らかにdatetime%zトークンdoes not respect the UTC offset form that has a colonのため、フォームがない場合でも、both are valid per the specとなっています。

+0

フォーマットはその十分厳しいですそれを単なる辛い方法で検証するのは難しくありません。 –

+0

そして、あなたは何を試しましたか...正確には何ですか? – jonrsharpe

+1

PyPI上の 'iso8601'パッケージを見ましたか? –

答えて

1

問題を抱えた場合、正規表現で簡単に解決できます。

>>> import re 
>>> re.match(r'^\d{4}-\d\d-\d\dT\d\d:\d\d:\d\d\.\d{6}[+-]\d\d:\d\d$', '2016-12-13T21:20:37.593194+00:00') 
<_sre.SRE_Match object; span=(0, 32), match='2016-12-13T21:20:37.593194+00:00'> 

あなたがISO 8601のすべてバリエーションを渡す必要がある場合は、それははるかに複雑な正規表現になりますが、それはまだ行うことができます。時間範囲が0〜23であることを確認するなど、数値範囲を検証する必要がある場合は、かっこを正規表現に入れてマッチグループを作成し、各グループを検証することもできます。ここで

+0

ありがとうございました!他の人がすでにこれを行っているので、私は自分自身の日付解析実装のロールバックを避けたかったのです。私は車輪を作り直すことを好まず、可能な限り、他の多くの人が使ってテストしたコードを使用する方が好きです。 – Stew

0

datetime.strptime()を使用して、粗けど(狭く質問の)機能的なソリューションです:

import datetime 

def is_expected_datetime_format(timestamp): 
    format_string = '%Y-%m-%dT%H:%M:%S.%f%z' 
    try: 
     colon = timestamp[-3] 
     if not colon == ':': 
      raise ValueError() 
     colonless_timestamp = timestamp[:-3] + timestamp[-2:] 
     datetime.datetime.strptime(colonless_timestamp, format_string) 
     return True 
    except ValueError: 
     return False 
0

https://www.safaribooksonline.com/library/view/regular-expressions-cookbook/9781449327453/ch04s07.html

ISO8601形式で日付と時刻を検証するための多くの変形(例えば、2008-08-を与えます30T01:45:36または2008-08-30T01:45:36.123Z)。あなたができる検証するために、そう

>>> regex = r'^(-?(?:[1-9][0-9]*)?[0-9]{4})-(1[0-2]|0[1-9])-(3[01]|0[1-9]|[12][0-9])T(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])(\.[0-9]+)?(Z|[+-](?:2[0-3]|[01][0-9]):[0-5][0-9])?$' 

:XMLスキーマのdateTimeタイプのための正規表現は、次のように与えられている

>>> import re 
>>> match_iso8601 = re.compile(regex).match 
>>> def validate_iso8601(str_val): 
...  try:    
...   if match_iso8601(str_val) is not None: 
...    return True 
...  except: 
...   pass 
...  return False 

いくつかの例:

>>> validate_iso8601('2017-01-01') 
False 

>>> validate_iso8601('2008-08-30T01:45:36.123Z') 
True 

>>> validate_iso8601('2016-12-13T21:20:37.593194+00:00') 
True 
関連する問題