18

私はタイムゾーンをたくさん扱い、それらを横断するプログラムを書いています。私が最も扱っている2つのことは、「今」から日時オブジェクトを作成してから、単純な日時オブジェクトをローカライズすることです。

これから太平洋のタイムゾーンで日時オブジェクトを作成するために、私は現在これを行っています(python 2.7.2+)

from datetime import datetime
import pytz
la = pytz.timezone("America/Los_Angeles")
now = datetime.now(la)

これはDSTに関して正しいですか?そうでない場合は、次のことを行う必要があると思います。

now2 = la.localize(datetime.now())

私の質問はなぜですか?最初が間違っていて、2番目が正しい場合を誰かに見せてもらえますか?

秒の質問については、カリフォルニア州ロサンゼルスで2012年9月1日の午前8時にユーザー入力から素朴な日時があったとします。このように日時を作成する正しい方法は次のとおりです。

la.localize(datetime(2012, 9, 1, 8, 0))

そうでない場合、これらの日時をどのように作成する必要がありますか?

4

4 に答える 4

30

pytzのドキュメントから:

時間の処理に適した方法は、常にUTCで作業し、人間が読み取る出力を生成する場合にのみ現地時間に変換することです。

utcnowしたがって、理想的には、の代わりにを使用する必要がありnowます。

何らかの理由で手を縛られて現地時間で作業する必要があると仮定すると、夏時間の移行ウィンドウ中に現在の時刻をローカライズしようとすると、問題が発生する可能性があります。同じdatetimeことが2回発生する可能性があります。1回は夏時間で、もう1回は標準時間であり、パラメータlocalizeで明示的に指定しない限り、メソッドは競合を解決する方法を知りません。is_dst

したがって、現在のUTC時刻を取得するには:

utc = pytz.timezone('UTC')
now = utc.localize(datetime.datetime.utcnow())

そしてそれをあなたの現地時間に変換するために(しかしあなたがしなければならないときだけ):

la = pytz.timezone('America/Los_Angeles')
local_time = now.astimezone(la)

編集: @JF Sebastianのコメントで指摘されているように、最初に使用した例datetime.now(tz)はすべての場合に機能します。上で概説したように、2番目の例は秋の移行中に失敗します。私は今でも、表示以外のすべてに現地時間の代わりにUTCを使用することを提唱しています。

于 2012-08-30T20:03:25.140 に答える
8

最初の解決策はDSTに関して正しく、2番目の解決策は悪いです。

例を挙げましょう。ここヨーロッパでは、このコードを実行すると:

from datetime import datetime
import pytz # $ pip install pytz

la = pytz.timezone("America/Los_Angeles")
fmt = '%Y-%m-%d %H:%M:%S %Z%z'
now = datetime.now(la)
now2 = la.localize(datetime.now())
now3 = datetime.now()
print(now.strftime(fmt))
print(now2.strftime(fmt))
print(now3.strftime(fmt))

私は次のようになります:

2012-08-30 12:34:06 PDT-0700
2012-08-30 21:34:06 PDT-0700
2012-08-30 21:34:06 

datetime.now(la)LAの現在の時刻に加えて、LAのタイムゾーン情報を使用して日時を作成します。

la.localize(datetime.now())ナイーブな日時にタイムゾーン情報を追加しますが、タイムゾーン変換は行いません。時刻がすでにこのタイムゾーンにあると想定しているだけです。

datetime.now()現地時間でナイーブな日時(タイムゾーン情報なし)を作成します。

LAにいる限り、違いはわかりませんが、コードが他の場所で実行された場合、おそらく期待どおりの結果が得られないでしょう。

それとは別に、タイムゾーンを真剣に扱う必要がある場合は、すべての時間をUTCで設定することをお勧めします。これにより、DSTに関する多くの問題を回避できます。

于 2012-08-30T19:57:34.040 に答える
3

これは機能します:

# naive datetime
d = datetime.datetime(2016, 11, 5, 16, 43, 45) 
utc = pytz.UTC # UTC timezone
pst = pytz.timezone('America/Los_Angeles') # LA timezone

# Convert to UTC timezone aware datetime
d = utc.localize(d) 
>>> datetime.datetime(2016, 11, 5, 16, 43, 45, tzinfo=<UTC>)

# show as in LA time zone (not converting here)
d.astimezone(pst) 
>>> datetime.datetime(2016, 11, 5, 9, 43, 45, 
tzinfo=<DstTzInfo 'America/Los_Angeles' PDT-1 day, 17:00:00 DST>)
# we get Pacific Daylight Time: PDT

# add 1 day to UTC date
d = d + datetime.timedelta(days=1) 
>>> datetime.datetime(2016, 11, 6, 16, 43, 45, tzinfo=<UTC>)

d.astimezone(pst) # now cast to LA time zone 
>>> datetime.datetime(2016, 11, 6, 8, 43, 45, 
tzinfo=<DstTzInfo 'America/Los_Angeles' PST-1 day, 16:00:00 STD>) 
# Daylight saving is applied -> we get Pacific Standard Time PST

これは動作しません:

# naive datetime
d = datetime.datetime(2016, 11, 5, 16, 43, 45) 
utc = pytz.UTC # UTC timezone
pst = pytz.timezone('America/Los_Angeles') # LA timezone

# convert to UTC timezone aware datetime
d = utc.localize(d) 
>>> datetime.datetime(2016, 11, 5, 16, 43, 45, tzinfo=<UTC>)

# convert to 'America/Los_Angeles' timezone: DON'T DO THIS
d = d.astimezone(pst) 
>>> datetime.datetime(2016, 11, 5, 9, 43, 45, 
tzinfo=<DstTzInfo 'America/Los_Angeles' PDT-1 day, 17:00:00 DST>) 
# we are in Pacific Daylight Time PDT

# add 1 day to LA local date: DON'T DO THAT
d = d + datetime.timedelta(days=1)
>>> datetime.datetime(2016, 11, 6, 9, 43, 45, 
tzinfo=<DstTzInfo 'America/Los_Angeles' PDT-1 day, 17:00:00 DST>) 
# Daylight Saving is NOT respected, we are still in PDT time, not PST

結論:

datetime.timedelta() 夏時間を考慮していません。

常にUTCタイムゾーンで時間の加算/減算を行ってください。出力/表示のためにのみ現地時間にキャストします。

于 2017-09-12T21:21:22.583 に答える
1

pytzのウェブサイトは言う:

残念ながら、標準の日時コンストラクターのtzinfo引数を使用すると、多くのタイムゾーンでpytzで「機能しません」。

したがって、を使用しないでくださいdatetime.now(la)。詳細はわかりませんが、一部のタイムゾーンは、以前よりもエキゾチックなルールで動作し、Pythonの日時コードではそれらを処理できません。pytzのコードを使用することで、pytzの目的であるため、正しく処理されるはずです。また、夏時間のジャンプ時間のおかげで2回発生する時間にも問題がある可能性があります。

2番目の質問に関しては、それはまさにドキュメントが示していることなので、あなたは良いはずです。

于 2012-08-30T19:14:47.130 に答える