在Python中如何将一个天真的datetime转换为DST感知的datetime? [英] How do you convert a naive datetime to DST-aware datetime in Python?

查看:146
本文介绍了在Python中如何将一个天真的datetime转换为DST感知的datetime?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在为返回原始Python数据时间的日历系统的后端工作。前端的工作方式是用户创建各种日历事件,前端返回其创建的事件的朴素版本(例如,如果用户从2020年3月4日下午4点至4点之间选择,前端将返回datetime.datetime(2020,10,5,15,0,0)作为开始,datetime.datetime(2011,10,5,16,0,0)作为结束。

I'm currently working on the backend for a calendaring system that returns naive Python datetimes. The way the front end works is the user creates various calendar events, and the frontend returns the naive version of the event they created (for example, if the user selects October 5, 2020 from 3:00pm-4:00pm, the frontend returns datetime.datetime(2020, 10, 5, 15, 0, 0) as the start and datetime.datetime(2011, 10, 5, 16, 0, 0) as the end.

我需要做的是采取天真的datetime并将其转换为UTC以存储在数据库中。系统的每个用户已经指定了他们的时区首选项,因此天真的datetime被认为是相同的时区作为其时区偏好显然,数据时间需要相对于UTC存储,以便如果用户更改其时区,现有的事件将仍然在正确的时间进行安排。

What I need to do is to take the naive datetime and convert it into UTC for storage in a database. Each user of the system has already specified their timezone preference, so the naive datetime is considered to be of the same timezone as their timezone preference. Obviously the datetimes need to be stored relative to UTC so that if users change their timezone, existing events will still render at the correct time that they scheduled them.

前端在我的控制之外,所以我无法更改我收到的数据。数据库设计也不在我的控制之下,所以我不能改变什么数据存储和如何。

The frontend is outside my control, so I can't change the data that I'm receiving. The database design is also outside my control, so I can't change what data is being stored and how.

以下是我迄今为止采用的近似方法:

Here is the approximate approach I have taken so far:

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)

我遇到的问题与夏令时间有关:

The problem I ran into is related to Daylight Savings Time:

>>> 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将时区设置为PST的PDT,而不考虑日期,这给了它8小时的UTC偏移,而不是预期的7小时DST偏移,所以时间最终被保存不正确。

Notice that using 'replace' sets the timezone to PST instead of PDT regardless of the date, which gives it a UTC offset of 8 hours instead of the expected 7 hours DST offset, so the time ends up being saved incorrectly.

我有什么选择将naive datetime转换为正确的PDT(或其他时区相对DST)tzinfo?

What options do I have for converting the naive datetime to the correct PDT (or other timezone-relative DST) tzinfo?

(另请注意,并不是所有的用户都生活在观察DST的时区,或者可能生活在不同时间切换的时区,因此为了做到这一点一个解决方案,如timedelta修正,在保存之前,我需要知道时区是否支持DST,在哪个日期切换)。

(Also, please note that not all users live in a timezone that observes DST, or may live in a timezone that switches over at different times, so in order to do a solution like a timedelta correction before saving, I would need to know if the timezone supports DST, and on which dates it switches over).

推荐答案

Pytz的 localize 函数可以这样做: http://pytz.sourceforge.net/#localized-times-and-date-arithmetic

Pytz's localize function can do this: http://pytz.sourceforge.net/#localized-times-and-date-arithmetic

from datetime import datetime
import pytz    

tz = pytz.timezone('US/Pacific')
naive_dt = datetime(2020, 10, 5, 15, 0, 0) 
utc_dt = tz.localize(naive_dt, is_dst=None).astimezone(pytz.utc)
# -> 2020-10-05 22:00:00+00:00

这篇关于在Python中如何将一个天真的datetime转换为DST感知的datetime?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆