RuntimeWarning:DateTimeField收到一个简单的日期时间


309

我正在尝试使用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)

Answers:


487

问题不在于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。


8
你在哪里写的tzinfo=<UTC>,是什么<UTC>?这不是我所看到的语法结构。
jameshfisher 2015年

4
聚会有点晚了,但是您看到的是从shell 输出的。更具体地说,是datetime对象的repr方法的输出,返回该对象的可打印信息。
乔治格里芬

36
在您使用的地方datetime.now,将其更改为timezone.now,然后from django.utils import timezone在顶部添加。
Unoti

12
对于仍在寻找该<UTC>部分的用户,您可以使用:import pytz datetime.datetime(2013, 11, 20, 20, 8, 7, 127325, tzinfo=pytz.UTC)
Anoyz

我的设置是USE_TZ = TrueTIME_ZONE = 'UTC'。但是,当我使用timezone.now()它时,它不会显示tzinfo=<UTC>..因此,此datetime对象被作为幼稚的对象传递。为什么会发生?
user3595632

71

使用django.utils.timezone.make_aware函数可让您的朴素日期时间对象意识到时区并避免这些警告。

它将原始的datetime对象(不带时区信息)转换为具有时区信息的对象(如果未将其明确指定为第二个参数,则使用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设置时区的日期的最符合Django的方法:)
sodimel

是否可以将其放在models.py中?
佛罗伦萨

@Florent,如果您默认使用utc时区,则无需更改模型中的任何内容,auto_now并且auto_now_add对于datetime字段可以正常工作。如果出于某种原因需要在模型中使时区感知当前日期时间对象,请使用django.utils.timezone.now()函数。
dmrz

26

只是为了解决错误以设置当前时间

from django.utils import timezone
import datetime

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

4
和datetime.datetime(9999,01,01,tzinfo = timezone.utc)
I. Yegor,

IMO这是最实用的解决方案
Ramtin

9

既可以修复警告也可以使用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 post。



3

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

from django.test import override_settings

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

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


2

如果您正在尝试将原始日期时间转换为带有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设置中带有时区的日期时间。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.