在Python(Django)中转换时区,添加神秘的30分钟

在Python(Django)中转换时区,添加神秘的30分钟,python,django,date,datetime,Python,Django,Date,Datetime,我有一个datetime对象,它被设置为2014-02-24 19:00:00+00:00,我相信它默认设置为UTC(通过Django管理面板) 这一次实际上是非洲/约翰内斯堡,所以我将其转换为: local_timezone= pytz.timezone("Africa/Johannesburg") local_time_start = self.start_time_unix.replace(tzinfo=local_timezone) utc_time = local_time_star

我有一个datetime对象,它被设置为
2014-02-24 19:00:00+00:00
,我相信它默认设置为UTC(通过Django管理面板)

这一次实际上是非洲/约翰内斯堡,所以我将其转换为:

local_timezone= pytz.timezone("Africa/Johannesburg")
local_time_start = self.start_time_unix.replace(tzinfo=local_timezone)
utc_time = local_time_start.astimezone(utc)
现在将输出
2014-02-2419:00:00+01:30

现在我想将其存储为转换后的UTC时区,因此我这样做:

local_timezone= pytz.timezone("Africa/Johannesburg")
local_time_start = self.start_time_unix.replace(tzinfo=local_timezone)
utc_time = local_time_start.astimezone(utc)
出于某种原因,这会输出
2014-02-24 17:30:00+00:00
。时间应该是17:00:00,那么额外的30分钟从哪里来

基本上,我试图将django管理面板中的给定输入作为models time_zone字段的本地时区,但将其存储为UTC


有没有更好的办法?Django文档解释了如何转换用户的本地时区,但我需要根据模型属性中的时区进行转换。

不要使用
datetime.replace()
替换为
pytz
时区。
pytz
时区包含历史时区数据(允许过去的日期使用UTC的正确偏移量),但是
datetime.replace()
在这种情况下无法使用正确的信息

请改用
时区.localize()
方法:

local_timezone = pytz.timezone("Africa/Johannesburg")
local_time_start = local_timezone.localize(self.start_time_unix)

仅在非时区感知对象上使用此选项。对于时区感知的
datetime
值,用于将值从一个时区转换为另一个时区:

local_timezone = pytz.timezone("Africa/Johannesburg")
local_time_start = self.start_time_unix.astimezone(local_timezone)
如果您的
datetime
值附加了错误的时区(它应该表示不同时区中的给定时间,而不是该时区中的不同时间),请先使用
.replace(tzinfo=None)删除旧时区,然后使用
timezone.localize()`:


不要使用
datetime.replace()
pytz
时区。
pytz
时区包含历史时区数据(允许过去的日期使用UTC的正确偏移量),但是
datetime.replace()
在这种情况下无法使用正确的信息

请改用
时区.localize()
方法:

local_timezone = pytz.timezone("Africa/Johannesburg")
local_time_start = local_timezone.localize(self.start_time_unix)

仅在非时区感知对象上使用此选项。对于时区感知的
datetime
值,用于将值从一个时区转换为另一个时区:

local_timezone = pytz.timezone("Africa/Johannesburg")
local_time_start = self.start_time_unix.astimezone(local_timezone)
如果您的
datetime
值附加了错误的时区(它应该表示不同时区中的给定时间,而不是该时区中的不同时间),请先使用
.replace(tzinfo=None)删除旧时区,然后使用
timezone.localize()`:


您的时区不正确,
+01:30
不是约翰内斯堡的时区。剩下的只是一个结果,结果是17:30,因为19:00-1:30=17:30。@vartec:时区是完全正确的,但只适用于历史日期。约翰内斯堡时区在某个时间点为+01:30。PyTZ时区对象反映了这一点。您的时区不正确,
+01:30
不是约翰内斯堡的时区。剩下的只是一个结果,结果是17:30,因为19:00-1:30=17:30。@vartec:时区是完全正确的,但只适用于历史日期。约翰内斯堡时区在某个时间点为+01:30。PyTZ时区对象反映了这一点。谢谢您的回答。当我尝试此操作时,我得到一个ValueError异常
Not naive datetime(tzinfo已经设置)
。你知道这是为什么吗?在这种情况下,你没有附加时区,你是在时区之间转换。为此,请使用
datetime.datetime.astimezone()
(请参阅更新的答案)。谢谢Martijn。问题是它已经认为这是UTC时间,所以astimezone将把19:00:00转换为21:00:00(因为它正在从UTC转换为约翰内斯堡)。我希望它将其更改为约翰内斯堡时间19:00:00。然后首先删除不正确的时区,然后使用
.localize()
;答案更新。谢谢你的回答。当我尝试此操作时,我得到一个ValueError异常
Not naive datetime(tzinfo已经设置)
。你知道这是为什么吗?在这种情况下,你没有附加时区,你是在时区之间转换。为此,请使用
datetime.datetime.astimezone()
(请参阅更新的答案)。谢谢Martijn。问题是它已经认为这是UTC时间,所以astimezone将把19:00:00转换为21:00:00(因为它正在从UTC转换为约翰内斯堡)。我希望它将其更改为约翰内斯堡时间19:00:00。然后首先删除不正确的时区,然后使用
.localize()
;答案已更新。