2011-01-26 21 views
11

NOTA: eliminé la pregunta tal como existía anteriormente y proporcioné solo la información relevante aquí.Django: problema de zona horaria

Nuestro servidor de base de datos (RH) tiene TIME_ZONE = "Europa/Londres" especificado. Y, dentro de Django settings.py, especificamos TIME_ZONE = "America/New_York".

Y, en mi clase de modelo que he indicado:

created = models.DateTimeField(editable=False,auto_now=False, auto_now_add=True) 
modified = models.DateTimeField(editable=False,auto_now=True, auto_now_add=True) 

Cuando luego ir a buscar los datos en el sitio de administración, llego la hora UTC/GMT en lugar de este.

Pensé que todo el tiempo se ajusta automágicamente por Django ya que especifiqué "America/New_York" como zona horaria de Django.

Se agradece cualquier ayuda/aclaración.

Gracias Eric

+0

¿Qué obtienes de esto? >>> import datetime >>> datetime.datetime.now() –

+0

Acabo de actualizar la información del SERVIDOR. La zona horaria está configurada en Servidor Europa/Londres. –

+0

Prefiero no usar AUTO_NOW. Se delega en el servidor de base de datos, que debe tener un conjunto de zona horaria. De esta manera, perderá flexibilidad para tener diferentes zonas horarias por usuario. –

Respuesta

10

Confiar en la fecha/hora 'automagic' es peligroso y estos parámetros del modelo auto_add son una trampa. Comprenda siempre la (s) zona (s) horaria (s) con las que está tratando. Python lo hace más fácil al asociar un miembro tzinfo a sus objetos datetime. Si bien estos objetos son 'ingenuos' de forma predeterminada, le recomiendo que siempre adjunte detalles de tzinfo. Todavía Python necesita ayuda adicional con python-dateutil o pytz (qué uso). Sin embargo, aquí hay una regla universal: siempre almacene sus fechas en una base de datos como UTC.

¿Por qué? Sus usuarios pueden estar en diferentes locales, teléfonos móviles y laptops, los servidores están mal configurados o duplicados en diferentes zonas horarias. Tantos dolores de cabeza Datetime nunca debe ser ingenuo y si son (como en una base de datos) y necesita el contexto, también incluir un campo de zona horaria en la tabla.

En su caso.

  1. No utilice los campos auto_now, use un save() personalizado en su lugar.
  2. Tienda UTC en la base de datos
  3. Si necesita conocer la zona horaria, por ejemplo, un evento de usuario, almacene la zona horaria en la base de datos también.
  4. convertido a la zona horaria necesaria/solicitado

Si está utilizando pytz, el método localize() es grande. El objeto datetime de Python tiene el útil replace() y astimezone().

Una nota más, si su base de datos es timezone naive (como MySQL) asegúrese de que sus fechas estén en UTC y luego use replace (tzinfo = None) porque el conector de la base de datos no puede manejar objetos tz-aware.

Aquí hay un thread con detalles en los campos auto_now de Django.

0

Desde que ha editado la pregunta, voy a editar mi respuesta :) Django no puede controlar la zona horaria de su base de datos, por lo que la manera de solucionar este problema es actualizar la zona horaria de su base de datos . Para MySQL, ejecutar esta consulta:

SELECT @@global.time_zone, @@session.time_zone;

Esto debería devolver SYSTEM, SYSTEM por defecto, que en su caso significa "Europa/Londres", y la causa de su problema. Ahora que ha verificado esto, siga las instrucciones en el primer comentario en esta página:

http://dev.mysql.com/doc/refman/5.5/en/time-zone-support.html

Recuerde reiniciar el servidor MySQL después de actualizar la zona horaria para que los cambios surtan efecto.

+0

Mientras DB almacene la compensación de zona horaria (no sé acerca de MySQL, pero Postgres hace esto con el tipo de datos "timestamp with timezone"), Django no debería preocuparse por la configuración de la base de datos, solo debería hacer los cálculos. A pesar de que Django se considera bastante independiente de DB, preferiblemente, Eric debería especificar qué servidor de bases de datos está ejecutando (nombre y versión), lo que ayudaría a la depuración. – drdaeman

1

Cuando dice auto_now_add = True, el valor será agregado por su servidor de base de datos y no por su servidor django. Por lo tanto, debe establecer la zona horaria en su servidor de base de datos.

3

En primer lugar, me gustaría almacenar mis datos como UTC porque es un buen punto de partida.

Así que déjame preguntarte, ¿Por qué necesitas tiempo en EST, es esto para el usuario final, o necesitas hacer lógica en el servidor y necesitarlo en EST?

Si es para el usuario final, una solución fácil es permitir que el navegador de los usuarios maneje la conversión a la hora correcta. En el servidor de convertir el objeto de fecha y hora a una marca de tiempo:

timestamp = time.mktime(datetime_obj.timetuple()) * 1000 

Y a continuación, en la página web de una instancia de un objeto Date:

var date_obj = new Date({{ timestamp }}); 
var datetime_string = date_obj.toString(); 
// the datetime_string will be in the users local timezone 

Ahora, por otro lado, si usted quiere tener el tiempo en la zona correcta en el servidor para que pueda realizar la lógica en él. Recomiendo usar la ayuda de python-dateutil. Se le permitirá cambiar fácilmente a una zona horaria diferente:

from datetime import datetime 
from dateutil import zoneinfo 

from_zone = zoneinfo.gettz('UTC') 
to_zone = zoneinfo.gettz('America/New_York') 

utc = created # your datetime object from the db 


# Tell the datetime object that it's in UTC time zone since 
# datetime objects are 'naive' by default 
utc = utc.replace(tzinfo=from_zone) 

# Convert time zone 
eastern_time = utc.aztimezone(to_zone) 

Ahora bien, si usted realmente quiere almacenar la fecha y hora en la EST, es necesario cambiar la hora en el servidor de base de datos (como Ajay Yadav y gorus dijeron). No sé por qué quieres guardarlos como EST, pero de nuevo no sé cuál es tu aplicación.

+0

Todd, supongo que mi pregunta no fue completa. Pero veo tus puntos y son buenos. Voy a usar algunos de tus ejemplos en mi proyecto actual. ¡Gracias! –

Cuestiones relacionadas