Python Django:tzinfo不适用于数据库插入。但为什么.now(local_tz)有效?

时间:2012-11-13 12:57:47

标签: python django timezone pytz

我正在使用Django。

设置中的

TIME_ZONE = 'Europe/Copenhagen'
USE_TZ = True

由于DST,时钟在2013-3-31跳过一小时。 01:59到03:00

我认为:

日期和时间以当地时间为准。我希望将这些插入为utc。

下面的代码正确保存为UTC,但是给RuntimeWarning:DateTimeField收到了一个天真的日期时间

the_date = datetime.datetime(2013, 3, 31, 1, 59)
hit = hits(date= the_date); hit.save(); # Correctly saved as 00:59:00

the_date = datetime.datetime(2013, 3, 31, 3, 1)
hit = hits(date= the_date); hit.save(); # Correctly saved as 01:01:00

我以为我可以通过让日期时间识别来避免警告。它确实避免了警告,但转换现在是错误的。

tz = timezone(settings.TIME_ZONE)
the_date = datetime.datetime(2013, 3, 31, 3, 1, tzinfo = tz)
hit = hits(date= the_date); hit.save(); # Incorrectly saved as 02:01:00

以下工作,没有运行时错误:

I have installed pytz.
the_date = local_tz.localize(datetime.datetime(2013, 3, 31, 3, 1))

回答我的问题:

我知道tzinfo不起作用,因为它没有考虑夏令时。好的,我不会用它。但是当以下情况似乎有效时我感到很困惑:

the_date = datetime.datetime.now(local_tz)

这正确地插入了冬天的utc(减去1小时以获得utc)以及当我将计算机系统时间改为夏天的某个日期(减去2小时以获得utc)时。

我的问题:

.now(local_tz)是否有效或者我测试错了吗?为什么这与tzinfo = tz不同?或者我使用tzinfo错了吗?

1 个答案:

答案 0 :(得分:0)

我建议尽快转换为UTC,并且仅在内部使用UTC。除了在时区(例如海洋船只)上移动并确实需要保存时区信息的情况外,对于恒定的时区情况,只需使用本地时间输入/输出并在用户界面将其转换为UTC就更简单了

要从localtime转换为UTC,您需要使用pytz.timezone.normalize方法来处理夏令时和其他时区转换。见section of the pytz documentation。在您的情况下,要将本地日期时间转换为UTC,您需要以下内容:

from pytz import timezone, utc

local_tz = timezone(settings.TIME_ZONE)
local_dt = datetime.datetime(2013, 3, 31, 3, 1, tzinfo = local_tz)
utc_dt = utc.normalize(local_dt.astimezone(utc))