RuntimeWarning:DateTimeField 收到一个天真的日期时间

Posted

技术标签:

【中文标题】RuntimeWarning:DateTimeField 收到一个天真的日期时间【英文标题】:RuntimeWarning: DateTimeField received a naive datetime 【发布时间】:2013-09-08 10:37:24 【问题描述】:

我正在尝试使用 IPython 发送一封简单的邮件。我没有设置任何仍然出现此错误的模型。可以做什么?

错误: /home/sourabh/Django/learn/local/lib/python2.7/site-packages/django/db/models/fields/init.py:827:RuntimeWarning:DateTimeField 收到一个幼稚的日期时间( 2013-09-04 14:14:13.698105) 时区支持处于活动状态。 运行时警告)

已尝试:第一步是将USE_TZ = True 添加到您的设置文件并安装pytz(如果可能)。

错误改变:

(learn)sourabh@sL:~/Django/learn/event$ python manage.py shell
/home/sourabh/Django/learn/local/lib/python2.7/site-packages/django/db/backends/sqlite3/base.py:53: RuntimeWarning: SQLite received a naive datetime (2013-09-05 00:59:32.181872) while time zone support is active.
  RuntimeWarning)

【问题讨论】:

【参考方案1】:

问题不在于 Django 设置,而在于传递给模型的 日期。以下是时区感知对象的外观:

>>> from django.utils import timezone
>>> import pytz
>>> timezone.now()
datetime.datetime(2013, 11, 20, 20, 8, 7, 127325, tzinfo=pytz.UTC)

这是一个幼稚的对象:

>>> from datetime import datetime
>>> datetime.now()
datetime.datetime(2013, 11, 20, 20, 9, 26, 423063)

因此,如果您要在任何地方传递电子邮件日期(最终到达某个模型),只需使用 Django 的 now()。如果不是,则可能是现有软件包的问题,​​它获取没有时区的日期,您可以修补软件包、忽略警告或将 USE_TZ 设置为 False。

【讨论】:

你写tzinfo=<UTC>的地方,<UTC>是什么?这不是我见过的句法结构。 聚会有点晚了,但您看到的是来自 shell 的 输出。更具体地说,它是 datetime 对象的 repr 方法的输出,它返回对象的可打印信息。 在您使用datetime.now的地方,将其更改为timezone.now,并在顶部添加from django.utils import timezone 对于那些仍在寻找 部分的人,您可以使用:import pytzdatetime.datetime(2013, 11, 20, 20, 8, 7, 127325, tzinfo=pytz.UTC) 我的设置是USE_TZ = TrueTIME_ZONE = 'UTC'。但是当我使用timezone.now() 时,它不会显示tzinfo=<UTC>....所以这个日期时间对象被作为幼稚的对象传递。为什么会这样?【参考方案2】:

使用django.utils.timezone.make_aware 函数让您的天真日期时间对象了解时区并避免这些警告。

它将天真的日期时间对象(没有时区信息)转换为具有时区信息的对象(如果您没有将其明确指定为第二个参数,则使用 django 设置中指定的时区):

import datetime
from django.conf import settings
from django.utils.timezone import make_aware

naive_datetime = datetime.datetime.now()
naive_datetime.tzinfo  # None

settings.TIME_ZONE  # 'UTC'
aware_datetime = make_aware(naive_datetime)
aware_datetime.tzinfo  # <UTC>

【讨论】:

感谢您的回答,这是最符合 django 的方式,可以将天真的日期转换为具有我的 django 设置时区的日期:) 可以把这个放到models.py中吗? @Florent 如果您默认使用 utc 时区,则无需更改模型中的任何内容,auto_nowauto_now_add 将适用于日期时间字段。如果您出于某种原因需要在模型中使用时区感知当前日期时间对象 - 使用 django.utils.timezone.now() 函数。【参考方案3】:

只是为了修复设置当前时间的错误

from django.utils import timezone
import datetime

datetime.datetime.now(tz=timezone.utc) # you can use this value

【讨论】:

对于 datetime.datetime(9999, 01, 01, tzinfo=timezone.utc) IMO 这是最实用的解决方案 from django.utils import timezone timezone.now() #也可以【参考方案4】:

可以修复警告使用settings.py中指定的时区,这可能与UTC不同。

例如在我的 settings.py 我有:

USE_TZ = True
TIME_ZONE = 'Europe/Paris'

这是一个解决方案;优点是str(mydate) 给出了正确的时间:

>>> from datetime import datetime
>>> from django.utils.timezone import get_current_timezone
>>> mydate = datetime.now(tz=get_current_timezone())
>>> mydate
datetime.datetime(2019, 3, 10, 11, 16, 9, 184106, 
    tzinfo=<DstTzInfo 'Europe/Paris' CET+1:00:00 STD>)
>>> str(mydate)
'2019-03-10 11:16:09.184106+01:00'

另一种等效方法是使用make_aware,请参阅 dmrz 帖子。

【讨论】:

【参考方案5】:

又快又脏 - 关掉它:

USE_TZ = False

在你的settings.py

【讨论】:

当USE_TZ为True且数据库支持时区(如PostgreSQL)时,设置此选项docs.djangoproject.com/en/2.2/ref/settings/#time-zone是错误的【参考方案6】:

如果您想在 django 中将天真的日期时间转换为带时区的日期时间,这是我的解决方案:

>>> import datetime
>>> from django.utils import timezone
>>> t1 = datetime.datetime.strptime("2019-07-16 22:24:00", "%Y-%m-%d %H:%M:%S")
>>> t1
    datetime.datetime(2019, 7, 16, 22, 24)
>>> current_tz = timezone.get_current_timezone()
>>> t2 = current_tz.localize(t1)
>>> t2
    datetime.datetime(2019, 7, 16, 22, 24, tzinfo=<DstTzInfo 'Asia/Shanghai' CST+8:00:00 STD>)
>>>

t1 是一个简单的日期时间,t2 是一个日期时间,在 django 的设置中带有时区。

【讨论】:

【参考方案7】:

您还可以覆盖设置,这在测试中特别有用:

from django.test import override_settings

with override_settings(USE_TZ=False):
    # Insert your code that causes the warning here
    pass

这将阻止您看到警告,同时您的代码中需要时区感知日期时间的任何内容都可能会给您带来问题。如果是这种情况,请参阅 kravietz 的回答。

【讨论】:

【参考方案8】:

在模型中,不要传值:

timezone.now()

相反,去掉括号,然后传递:

timezone.now

如果您继续收到运行时错误警告,请考虑将模型字段从 DateTimeField 更改为 DateField。

【讨论】:

【参考方案9】:

确保 settings.py 有 USE_TZ = True

在你的 python 文件中:

from django.utils import timezone

timezone.now() # use its value in model field

【讨论】:

以上是关于RuntimeWarning:DateTimeField 收到一个天真的日期时间的主要内容,如果未能解决你的问题,请参考以下文章

Pycharm 更新到 2016.2 后导入 RuntimeWarning

Django 中 DateField 的 RuntimeWarning

RuntimeWarning:DateTimeField 收到一个天真的日期时间,具有正确的时区和设置

RuntimeWarning:在除法中遇到无效值

RuntimeWarning:DateTimeField 收到一个天真的日期时间

RuntimeWarning:Glyph 21435 missing from current font.