web-dev-qa-db-ja.com

Python:datetime / timestampをあるタイムゾーンから別のタイムゾーンに変換するにはどうすればよいですか?

具体的には、サーバーのタイムゾーン(システム時間の観点)とタイムゾーン入力を考慮して、(夏時間などに関係なく)新しいタイムゾーンであるかのようにシステム時間を計算するにはどうすればよいですか?

import datetime
current_time = datetime.datetime.now() #system time

server_timezone = "US/Eastern"
new_timezone = "US/Pacific"

current_time_in_new_timezone = ???
20
kfan

Originのタイムゾーンと変換後の新しいタイムゾーンがわかっている場合は、最初に_pytz.localize_を使用してローカライズ(夏時間など)を処理し、次に_pytz.timezone_を使用してタイムゾーンオブジェクトを作成します。最後に、簡単な計算のためにdatetime.astimezone(timezone)を使用します。例えば:

_import datetime
import pytz # new import

my_timestamp = datetime.datetime.now() # some timestamp
old_timezone = pytz.timezone("US/Eastern")
new_timezone = pytz.timezone("US/Pacific")

# returns datetime in the new timezone
my_timestamp_in_new_timezone = old_timezone.localize(my_timestamp).astimezone(new_timezone) 
_

そしてもちろん、特定のタイムゾーンの現在の時刻が必要な場合は、そのタイムゾーンを直接datetime.now()に渡してタイムスタンプを取得できます。このような:

_datetime.datetime.now(new_timezone)
_

以上のことを踏まえて、すべてのタイムスタンプをシステム標準としてUTCに保存し、DST全体の問題を回避することを強くお勧めします。このコンテキストについては、次を参照してください: http://lucumr.pocoo.org/2011/7/15/eppur-si-muove/

そして、一般的に時間計算を処理することがどれほど難しいかを知るために: http://yourcalendricalfallacyis.com

22
kfan

日時/タイムスタンプをあるタイムゾーンから別のタイムゾーンに変換するにはどうすればよいですか?

2つのステップがあります。

  1. システム時刻とタイムゾーンから認識された日時オブジェクトを作成しますたとえば、指定されたタイムゾーンの現在のシステム時刻を取得します。

    _#!/usr/bin/env python
    from datetime import datetime
    import pytz
    
    server_timezone = pytz.timezone("US/Eastern")
    server_time = datetime.now(server_timezone) # you could pass *tz* directly
    _

    注: datetime.now(server_timezone)はあいまいな時間でも機能します たとえば、DSTの移行中にserver_timezone.localize(datetime.now())が失敗する可能性があります(50%の確率)。

    入力時間がサーバーのタイムゾーンに存在し、それが一意であることが確かな場合は、_is_dst=None_を渡して次のことをアサートできます。

    _server_time = server_timezone.localize(naive_time, is_dst=None)
    _

    無効な時間の例外が発生します。
    1日までのエラー(通常、DSTによるエラーは1時間)次に、_is_dst_パラメータを削除できます:

    _server_time = server_timezone.normalize(server_timezone.localize(naive_time))
    _

    .normalize()は、存在しない時間を調整するために呼び出されます(ギャップ内のローカル時間、「スプリングフォワード」遷移中)。タイムゾーンのルールが変更されていない場合。サーバーは存在しない時間を生成するべきではありません。参照 "いつでもis_dst = Trueを設定できますか?"

  2. 対象の日時オブジェクトをターゲットのタイムゾーンに変換しますtz

    _tz = pytz.timezone("US/Pacific")
    server_time_in_new_timezone = server_time.astimezone(tz)
    _
3
jfs