Tengo un timestamptz
campo consciente de la zona horaria en PostgreSQL. Cuando extraigo datos de la tabla, quiero restar el tiempo ahora mismo para poder obtener su edad.
El problema que estoy teniendo es que tanto datetime.datetime.now()
y datetime.datetime.utcnow()
parecen volver de zona horaria marcas de tiempo sin darse cuenta, lo que da lugar a mí conseguir este error:
TypeError: can't subtract offset-naive and offset-aware datetimes
¿Hay alguna manera de evitar esto (preferiblemente sin un módulo de terceros que se utiliza)
EDITAR: Gracias por las sugerencias, sin embargo, tratar de ajustar la zona horaria parece darme errores ... así que solo voy a usar marcas de tiempo inconscientes de la zona horaria en PG y siempre inserto usando:
NOW() AT TIME ZONE 'UTC'
De esa manera, todas mis marcas de tiempo son UTC por defecto (aunque es más molesto hacer esto).
datetime.timezone.utc
opytz.utc
. Por ejemplo,1970-01-01 00:00:00
es ambiguo y hay que agregar una zona horaria para eliminar la ambigüedad:1970-01-01 00:00:00 UTC
. Ya ves, tienes que agregar nueva información; la marca de tiempo en sí misma es ambigua.utcnow
no debería devolver un objeto ingenuo o una marca de tiempo sin una zona horaria. De los documentos, "Un objeto consciente se utiliza para representar un momento específico en el tiempo que no está abierto a interpretación". Cualquier momento en UTC cumple con este criterio, por definición.La solución correcta es agregar la información de la zona horaria, por ejemplo, para obtener la hora actual como un objeto de fecha y hora consciente en Python 3:
En versiones anteriores de Python, puede definir el
utc
objeto tzinfo usted mismo (ejemplo de documentos de fecha y hora):luego:
fuente
Sé que algunas personas usan Django específicamente como interfaz para abstraer este tipo de interacción con la base de datos. Django proporciona utilidades que pueden usarse para esto:
Debe configurar una infraestructura básica de configuración de Django, incluso si solo está utilizando este tipo de interfaz (en la configuración, debe incluirla
USE_TZ=True
para obtener una fecha y hora consciente).Por sí solo, esto probablemente no sea lo suficientemente cercano como para motivarte a usar Django como interfaz, pero hay muchas otras ventajas. Por otro lado, si tropezó aquí porque estaba destrozando su aplicación Django (como lo hice), entonces quizás esto ayude ...
fuente
USE_TZ=True
, para obtener una fecha y hora consciente aquí.+ timedelta(hours=5, minutes=30)
ISTEsta es una solución muy simple y clara.
Dos líneas de código.
Conclusión: debe administrar sus variables de fecha y hora con la misma información de hora
fuente
diff = datetime.now(timezone.utc) - your_timezone_aware_variable
funciona (y la(a - b)
fórmula anterior es la explicación de por qué(a - b)
puede funcionar incluso sia.tzinfo
no es asíb.tzinfo
).El módulo psycopg2 tiene sus propias definiciones de zona horaria, así que terminé escribiendo mi propio contenedor alrededor de utcnow:
y utilícelo
pg_utcnow
siempre que necesite la hora actual para comparar con un PostgreSQLtimestamptz
fuente
También enfrenté el mismo problema. Luego encontré una solución después de mucha búsqueda.
El problema era que cuando obtenemos el objeto de fecha y hora del modelo o formulario, es consciente de la compensación y si obtenemos la hora por sistema, es una compensación ingenua .
Entonces, lo que hice es obtener la hora actual usando timezone.now () e importar la zona horaria desde django.utils import timezone y poner USE_TZ = True en el archivo de configuración del proyecto.
fuente
Se me ocurrió una solución ultra simple:
Funciona con valores de fecha y hora que reconocen la zona horaria y no son ingenuos. Y no se requieren bibliotecas adicionales ni soluciones alternativas a la base de datos.
fuente
He encontrado que
timezone.make_aware(datetime.datetime.now())
es útil en django (estoy en 1.9.1). Desafortunadamente, no puede simplemente hacer que undatetime
objeto sea consciente del desplazamiento, entoncestimetz()
. Tienes que hacer unadatetime
y hacer comparaciones basadas en eso.fuente
¿Hay alguna razón apremiante por la que no puede manejar el cálculo de la edad en PostgreSQL? Algo como
fuente
Sé que esto es viejo, pero pensé que agregaría mi solución en caso de que alguien la encuentre útil.
Quería comparar la fecha y hora local ingenua con una fecha y hora consciente de un servidor de tiempo. Básicamente, creé un nuevo objeto de fecha y hora ingenuo usando el objeto de fecha y hora consciente. Es un truco y no se ve muy bonito, pero hace el trabajo.
... aquí viene el dulce de azúcar ...
fuente
utc_to_local()
de mi respuesta devuelve la hora local como un objeto de fecha y hora consciente (es el código Python 3.3+)delta = response.tx_time - time.time()
.