RuntimeWarning: DateTimeField recibió una fecha y hora ingenua


310

Estoy tratando de enviar un correo simple usando IPython. No he configurado ningún modelo que todavía reciba este error. ¿Qué se puede hacer?

Error: /home/sourabh/Django/learn/local/lib/python2.7/site-packages/django/db/models/fields/ init .py: 827: RuntimeWarning: DateTimeField recibió una fecha y hora ingenua (2013-09-04 14: 14: 13.698105) mientras el soporte de zona horaria está activo. RuntimeWarning)

Probado: el primer paso es agregar USE_TZ = Truea su archivo de configuración e instalar pytz(si es posible).

Error cambiado:

(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)

Respuestas:


490

El problema no está en la configuración de Django, sino en la fecha pasada al modelo. Así es como se ve un objeto con reconocimiento de zona horaria:

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

Y aquí hay un objeto ingenuo:

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

Entonces, si está pasando la fecha de correo electrónico en cualquier lugar (y eventualmente llega a algún modelo), solo use Django now(). De lo contrario, probablemente sea un problema con un paquete existente que recupera la fecha sin zona horaria y puede parchear el paquete, ignorar la advertencia o establecer USE_TZ en False.


8
¿Dónde escribes tzinfo=<UTC>, qué es <UTC>? Esa no es una construcción sintáctica que he visto.
jameshfisher

44
Un poco tarde para la fiesta, pero lo que está viendo es la salida del shell. Más específicamente, es la salida del método repr del objeto datetime , que devuelve información imprimible del objeto.
George Griffin

36
En los lugares donde estaba usando datetime.now, cámbielo timezone.nowy agregue from django.utils import timezoneen la parte superior.
Unoti

12
Para aquellos que todavía buscan esa parte <UTC>, pueden usar esto:import pytz datetime.datetime(2013, 11, 20, 20, 8, 7, 127325, tzinfo=pytz.UTC)
Anoyz

Mis valores son USE_TZ = True, TIME_ZONE = 'UTC'. Pero cuando lo uso timezone.now()no se muestra tzinfo=<UTC>... Así que este objeto de fecha y hora se pasa como ingenuo. ¿Por que sucede?
user3595632

71

Use la función django.utils.timezone.make_aware para hacer que sus ingenuos datetime sean conscientes de la zona horaria y evitar esas advertencias.

Convierte el objeto de fecha y hora ingenuo (sin información de zona horaria) en el que tiene información de zona horaria (usando la zona horaria especificada en la configuración de django si no la especifica explícitamente como un segundo argumento):

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>

Gracias por esta respuesta, es la forma más compatible con django para transformar fechas ingenuas en fechas con la zona horaria de mi configuración de django :)
sodimel

¿Es posible poner esto en models.py?
Florent

@Florent no hay necesidad de cambiar nada en los modelos si usa la zona horaria utc por defecto, auto_nowy auto_now_addfuncionará bien para los campos de fecha y hora. Si necesita tener un objeto de fecha y hora actual consciente de la zona horaria en los modelos por alguna razón, use la django.utils.timezone.now()función.
dmrz

26

Solo para corregir el error y configurar la hora actual

from django.utils import timezone
import datetime

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

44
y para datetime.datetime (9999, 01, 01, tzinfo = timezone.utc)
I. Yegor

OMI, esta es la solución más práctica
Ramtin

9

Uno puede arreglar la advertencia y usar la zona horaria especificada en settings.py, que puede ser diferente de UTC.

Por ejemplo, en mi settings.py tengo:

USE_TZ = True
TIME_ZONE = 'Europe/Paris'

Aquí hay una solución; La ventaja es que str(mydate)da el tiempo correcto:

>>> 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'

Se está utilizando otro método equivalente make_aware, consulte la publicación de dmrz.



3

También puede anular la configuración, particularmente útil en las pruebas:

from django.test import override_settings

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

Esto evitará que vea la advertencia, al mismo tiempo, cualquier cosa en su código que requiera una fecha y hora consciente de la zona horaria puede causarle problemas. Si este es el caso, vea la respuesta de kravietz.


2

Si está tratando de transformar una fecha y hora ingenua en una fecha y hora con zona horaria en django, aquí está mi solución:

>>> 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 es una fecha y hora ingenua y t2 es una fecha y hora con zona horaria en la configuración de django.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.