私は現在、単純な Python 日時を返すカレンダー システムのバックエンドに取り組んでいます。フロントエンドが機能する方法は、ユーザーがさまざまなカレンダー イベントを作成し、フロントエンドが作成したイベントのナイーブ バージョンを返すことです (たとえば、ユーザーが 2020 年 10 月 5 日の午後 3:00 から午後 4:00 までを選択した場合、フロントエンドは次を返します)。datetime.datetime(2020, 10, 5, 15, 0, 0)
始まりdatetime.datetime(2011, 10, 5, 16, 0, 0)
として、そして終わりとして。
私がする必要があるのは、単純な日時を取得し、データベースに格納するために UTC に変換することです。システムの各ユーザーはすでにタイムゾーン設定を指定しているため、単純な datetime はタイムゾーン設定と同じタイムゾーンであると見なされます。ユーザーがタイムゾーンを変更した場合でも、既存のイベントがスケジュールした正しい時刻にレンダリングされるように、日時は UTC を基準にして格納する必要があることは明らかです。
フロントエンドは私の管理外にあるため、受信しているデータを変更することはできません。データベースの設計も私の手に負えないので、どのデータをどのように保存するかを変更することはできません。
これまでに私が取ったおおよそのアプローチは次のとおりです。
import pytz
def convert_to_UTC(naive_datetime, user_tz_preference):
user_datetime = naive_datetime.replace(tzinfo=user_tz_preference)
utc_datetime = user_datetime.astimezone(pytz.utc)
私が遭遇した問題は、夏時間に関連しています。
>>> from datetime import datetime
>>> import pytz
>>> user_tz_preference = pytz.timezone('US/Pacific')
>>> naive_datetime = datetime(2011, 10, 26, 12, 0, 0)
>>> user_datetime = naive_datetime.replace(tzinfo=user_tz_preference)
>>> user_datetime
datetime.datetime(2011, 10, 26, 12, 0, tzinfo=<DstTzInfo 'US/Pacific' PST-1 day, 16:00:00 STD>)
>>> received_utc = user_datetime.astimezone(pytz.utc)
>>> received_utc
datetime.datetime(2011, 10, 26, 20, 0, tzinfo=<UTC>)
>>> expected_utc = datetime(2011, 10, 26, 19, 0, tzinfo=pytz.utc)
>>> expected_utc == received_utc
False
「replace」を使用すると、日付に関係なく、タイムゾーンが PDT ではなく PST に設定されることに注意してください。これにより、予想される 7 時間の DST オフセットではなく 8 時間の UTC オフセットが与えられるため、時間が正しく保存されなくなります。
ナイーブな日時を正しい PDT (または他のタイムゾーン相対 DST) tzinfo に変換するためにどのようなオプションがありますか?
(また、すべてのユーザーが DST を観察するタイムゾーンに住んでいるわけではないことに注意してください。または、異なる時間に切り替わるタイムゾーンに住んでいる可能性があるため、保存する前にタイムデルタ補正のような解決策を実行するには、タイムゾーンは DST をサポートし、どの日付に切り替わるか)。