web-dev-qa-db-ja.com

Python datetime strptime()およびstrftime():タイムゾーン情報を保存する方法

次のコードを参照してください。

import datetime
import pytz

fmt = '%Y-%m-%d %H:%M:%S %Z'

d = datetime.datetime.now(pytz.timezone("America/New_York"))
d_string = d.strftime(fmt)
d2 = datetime.datetime.strptime(d_string, fmt)
print d_string 
print d2.strftime(fmt)

出力は

2013-02-07 17:42:31 EST
2013-02-07 17:42:31 

タイムゾーン情報は、翻訳で失われました。

「%Z」を「%z」に切り替えると、

ValueError: 'z' is a bad directive in format '%Y-%m-%d %H:%M:%S %z'

python-dateutilを使用できることはわかっていますが、datetimeでこの単純な機能を実現できず、依存関係をさらに導入する必要があるのは奇妙なことです。

49
CodeNoob

ここでの問題の一部は、タイムゾーンを表すために通常使用される文字列が実際には一意ではないことです。 「EST」は、北米の人々にとって「アメリカ/ニューヨーク」のみを意味します。これはC time APIの制限であり、Pythonソリューションは…誰かがPEPを書こうとするなら、将来のバージョンで完全なtz機能をいつでも追加することです。

canオフセットとしてタイムゾーンをフォーマットおよび解析しますが、夏時間/夏時間の情報は失われます(たとえば、夏には "America/Phoenix"と "America/Los_Angeles"を区別できません) 。タイムゾーンを3文字の略語としてフォーマットできますが、それから解析することはできません。

あいまいであいまいなものが必要な場合、通常は必要なものを使用するには、dateutilなどのサードパーティライブラリが必要です。

実際に明確なものが必要な場合は、実際のtz名をローカルの日時文字列に自分で追加し、もう一方の端でそれを分割します。

d = datetime.datetime.now(pytz.timezone("America/New_York"))
dtz_string = d.strftime(fmt) + ' ' + "America/New_York"

d_string, tz_string = dtz_string.rsplit(' ', 1)
d2 = datetime.datetime.strptime(d_string, fmt)
tz2 = pytz.timezone(tz_string)

print dtz_string 
print d2.strftime(fmt) + ' ' + tz_string

または...これら2つの中間点で、既にpytzライブラリを使用しています。これは、「EST」などの形式を解析できます(arbitrary意的ではあるが明確に定義された曖昧性除去規則に従って)。したがって、本当にしたい場合は、%Zをフォーマット側に残し、それを取り出してpytz.timezone()で解析してから、残りをstrptimeに渡すことができます。

31
abarnert

残念ながら、strptime()はOSによって設定されたタイムゾーンのみを処理でき、実際にはタイムオフセットとしてのみ処理できます。 ドキュメント から:

%Zディレクティブのサポートは、tznameに含まれる値とdaylightがtrueであるかどうかに基づいています。このため、UTCとGMTを認識することを除いて、プラットフォーム固有です。UTCとGMTは常に既知であり(夏時間以外のタイムゾーンと見なされます)。

strftime()%zを公式にサポートしていません。

タイムゾーンの解析をサポートするためにpython-dateutilに固執しています。

11
Martijn Pieters

これはPython 2.7での私の答えです

タイムゾーンで現在の時刻を印刷する

from datetime import datetime
import tzlocal  # pip install tzlocal

print datetime.now(tzlocal.get_localzone()).strftime("%Y-%m-%d %H:%M:%S %z")

特定のタイムゾーンで現在の時刻を印刷する

from datetime import datetime
import pytz # pip install pytz

print datetime.now(pytz.timezone('Asia/Taipei')).strftime("%Y-%m-%d %H:%M:%S %z")

それは次のようなものを印刷します

2017-08-10 20:46:24 +0800
1
Johnny