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

Posted

技术标签:

【中文标题】Python Django:tzinfo 不适用于数据库插入。但是为啥 .now(local_tz) 有效?【英文标题】:Python Django: tzinfo doesn't work for DB insertion. But why does .now(local_tz) work?Python Django:tzinfo 不适用于数据库插入。但是为什么 .now(local_tz) 有效? 【发布时间】:2012-11-01 21:44:02 【问题描述】:

我正在使用 Django。

在设置中:

TIME_ZONE = 'Europe/Copenhagen'
USE_TZ = True

由于 DST,2013 年 3 月 31 日时钟会跳过一个小时。 01:59 转到 03:00

我的观点:

日期和时间以当地时间给出。我希望这些以 UTC 格式插入。

以下代码正确保存为 UTC,但给出 RuntimeWarning: DateTimeField received a naive datetime

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)

这在冬季(减去 1 小时得到 utc)和我将计算机系统时间更改为夏天的日期(减去 2 小时得到 utc)时都正确插入为 utc。

我的问题:

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

【问题讨论】:

【参考方案1】:

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

要将本地时间转换为 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))

【讨论】:

它也适用于 localize(),包括 dst。我可以很好地插入(至少我是这么认为的)。问题是为什么 datetime.now(local_tz) 在设置 tzinfo 时不起作用?我可以像这样使用 datetime.now(local_tz) 吗? (我很想看到一个规范化工作的例子,但本地化没有,但这真的是另一个问题......) 似乎在某些情况下normalize 确实是必要的,尽管我现在不能给你一个例子。我会留下答案以供参考。无论如何,如果您的时区是不变的,我真的建议您始终在内部使用 UTC,并且只在输入/输出中从/到本地时间转换:它会为您省去一些麻烦。 是的,我同意尽可能使用 UTC。但我真正想要的是理解这些东西,而不仅仅是一种可行的方式。这是我不明白的。 (有时我会得到当地时间的日期。我需要处理这些。) 我只能支持并同意您需要了解事情的运作方式!祝你的研究好运,如果你发现一些有趣的东西,请告诉我们。 :)

以上是关于Python Django:tzinfo 不适用于数据库插入。但是为啥 .now(local_tz) 有效?的主要内容,如果未能解决你的问题,请参考以下文章

Django模板标签切片不适用于表单切片

django unique together 不适用于无日期时间 [重复]

JWT 身份验证不适用于 Django 中的自定义控制器

form-horizo​​ntal 不适用于 django-crispy-forms 和 django-registration-redux

Python 错误:此方法仅适用于类,不适用于实例

使用邮递员的 GET 请求有效,但不适用于 python (HTTPSConnectionPool)