重複の可能性:
Python strptime() とタイムゾーン?
'Saturday, December 22, 2012 1:22:24 PM EST' does not match format '%A, %B %d, %Y %I:%M:%S %p %Z'
多分私は何かが欠けているかもしれませんが、これが適切に検証されない理由を誰でも見つけることができますか?
重複の可能性:
Python strptime() とタイムゾーン?
'Saturday, December 22, 2012 1:22:24 PM EST' does not match format '%A, %B %d, %Y %I:%M:%S %p %Z'
多分私は何かが欠けているかもしれませんが、これが適切に検証されない理由を誰でも見つけることができますか?
このstrptime()
関数は、%Z
タイムゾーンの解析をうまく処理できません。実際にサポートされているのは UTC と GMT のみで、現在のtime.tzname
. ドキュメントを参照してstrptime
ください:
ディレクティブのサポートは、 およびが trueであるかどうか
%Z
に含まれる値に基づいています。このため、常に知られている UTC と GMT を認識することを除いて、プラットフォーム固有です (そして、夏時間以外のタイムゾーンと見なされます)。tzname
daylight
EST
入力の%Z
一部とフォーマット文字列の一部を削除すると、機能します。
>>> import time
>>> time.strptime('Saturday, December 22, 2012 1:22:24 PM EST', '%A, %B %d, %Y %I:%M:%S %p %Z')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/_strptime.py", line 454, in _strptime_time
return _strptime(data_string, format)[0]
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/_strptime.py", line 325, in _strptime
(data_string, format))
ValueError: time data 'Saturday, December 22, 2012 1:22:24 PM EST' does not match format '%A, %B %d, %Y %I:%M:%S %p %Z'
>>> time.strptime('Saturday, December 22, 2012 1:22:24 PM', '%A, %B %d, %Y %I:%M:%S %p')
time.struct_time(tm_year=2012, tm_mon=12, tm_mday=22, tm_hour=13, tm_min=22, tm_sec=24, tm_wday=5, tm_yday=357, tm_isdst=-1)
またはタイムゾーンEST
をGMT
次のように置き換えます。
>>> time.strptime('Saturday, December 22, 2012 1:22:24 PM GMT', '%A, %B %d, %Y %I:%M:%S %p %Z')
time.struct_time(tm_year=2012, tm_mon=12, tm_mday=22, tm_hour=13, tm_min=22, tm_sec=24, tm_wday=5, tm_yday=357, tm_isdst=0)
time.tzname
、GMT
または以外のタイムゾーンの文字列を解析するUTC
には、別の日付解析ライブラリを使用します。dateutil
ライブラリには、タイムゾーンを適切に処理する優れたparse
機能があります。
>>> from dateutil.parser import parse
>>> parse('Saturday, December 22, 2012 1:22:24 PM EST', tzinfos={'EST': -18000})
datetime.datetime(2012, 12, 22, 13, 22, 24, tzinfo=tzoffset(u'EST', -18000))
ただし、使用dateutil.parser.parse()
する場合は、フォーマットに独自のタイムゾーン オフセットを指定する必要があります。
多くの手間を省き、 dateutilを使用できます。
In [1]: from dateutil import parser
In [2]: parser.parse('Saturday, December 22, 2012 1:22:24 PM EST')
Out[2]: datetime.datetime(2012, 12, 22, 13, 22, 24)
eumiroが指摘したあいまいさについては、次のようなtzinfo
引数を追加できます。
In [3]: parser.parse('Saturday, December 22, 2012 1:22:24 PM EST',tzinfos={'EST':-5*3600})
Out[3]: datetime.datetime(2012, 12, 22, 13, 22, 24, tzinfo=tzoffset('EST', -18000))
@root が示唆したように、dateutil.parser は日付を解析する堅牢な方法ですが、ここで問題について明確にするためだけに
_strptime.py のコードを見たところ、サポートされているタイムゾーンは
["utc", "gmt", time.tzname[0].lower()]
現在のロケールのタイムゾーンが夏時間をサポートしている場合は、追加されます
time.tzname[0].lower()
上記のリストに。
したがって、strptime を使用する場合は、日付を解析しているタイムゾーンがソースのタイムゾーンをサポートしていることを確認してください。
参考にしたコードはこちら
def __calc_timezone(self):
# Set self.timezone by using time.tzname.
# Do not worry about possibility of time.tzname[0] == timetzname[1]
# and time.daylight; handle that in strptime .
try:
time.tzset()
except AttributeError:
pass
no_saving = frozenset(["utc", "gmt", time.tzname[0].lower()])
if time.daylight:
has_saving = frozenset([time.tzname[1].lower()])
else:
has_saving = frozenset()
self.timezone = (no_saving, has_saving)
ほとんどの場合、ロケールのタイムゾーンは空です。たとえば、次の%Z
ように評価され''
ます。これは次の方法でテストできます。
>>> fmt = '%A, %B %d, %Y %I:%M:%S %p %Z'
>>> datetime.strptime(datetime.strftime(datetime.now(), fmt), fmt)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/_strptime.py", line 325, in _strptime
(data_string, format))
ValueError: time data 'Friday, December 28, 2012 11:34:35 AM ' does not match format '%A, %B %d, %Y %I:%M:%S %p %Z'