Manejo de Zonas Horarias en Aplicaciones Django: De la Creación al Despliegue

El manejo de zonas horarias en un proyecto de Django puede ser un poco complejo debido a las diferentes configuraciones posibles en varios niveles. Aquí está la forma en que generalmente funcionan estos tres niveles:

Configuración del Proyecto Django (settings.py):

En el archivo settings.py de tu proyecto Django, puedes configurar la zona horaria para toda la aplicación utilizando la variable TIME_ZONE. Esta configuración determina cómo se manejarán las fechas y horas en tu aplicación a menos que se anule en otros niveles. Django utiliza esta configuración para mostrar y almacenar fechas en la zona horaria especificada.

Si deseas imprimir la zona horaria actual desde el shell de Python, puedes hacerlo de la siguiente manera:

from django.utils import timezone
# Obtén la zona horaria actual
current_timezone = timezone.get_current_timezone()
# Imprime la zona horaria actual
print(current_timezone)

image

Configuración de la Base de Datos:

La mayoría de los sistemas de gestión de bases de datos (como MySQL, PostgreSQL) almacenan las fechas en UTC por defecto. Esto significa que cuando almacenas una fecha en la base de datos, se almacena en UTC sin importar la zona horaria que hayas configurado en tu proyecto Django. Cuando recuperas una fecha de la base de datos, Django automáticamente la convierte a la zona horaria configurada en TIME_ZONE antes de mostrarla en tu aplicación.

Verifica la Configuración Actual: Puedes verificar la configuración actual de la zona horaria ejecutando el siguiente comando SQL en MySQL:

SELECT @@global.time_zone;

Esto te mostrará la configuración actual de la zona horaria global. Si muestra "SYSTEM", significa que MySQL está utilizando la zona horaria del sistema. image

Cambia la Configuración a UTC: Para cambiar la configuración a UTC, puedes ejecutar el siguiente comando SQL en MySQL:

SET GLOBAL time_zone = '+00:00';

Verifica la Nueva Configuración: Para asegurarte de que la configuración se haya aplicado correctamente, puedes volver a ejecutar el comando para verificar la zona horaria:

SELECT @@global.time_zone;

image

Configurar la base de datos en UTC es una práctica común y recomendada en muchas aplicaciones web. UTC es una zona horaria estándar que no está sujeta a cambios de horario de verano ni a ajustes estacionales, lo que facilita la gestión de fechas y horas en aplicaciones distribuidas globalmente.

Configuración del Sistema Operativo (Linux):

La zona horaria del sistema operativo también puede afectar cómo se muestran y almacenan las fechas. La configuración del sistema operativo se utiliza principalmente para establecer la hora del sistema y afecta a todas las aplicaciones en ese sistema. Sin embargo, la configuración del sistema operativo generalmente no debería influir en la forma en que Django almacena o muestra las fechas en tu aplicación, siempre que se configure correctamente en Django.

En Ubuntu y otros sistemas Linux, puedes utilizar el siguiente comando para obtener la zona horaria actual:

timedatectl

image

Para cambiar la zona horaria en Ubuntu y otros sistemas Linux, puedes editar el archivo /etc/timezone. Puedes utilizar un editor de texto en la terminal, como nano o vi, para modificar este archivo. Aquí tienes un ejemplo de cómo hacerlo con nano:

  1. Abre una terminal.
  2. Ejecuta el siguiente comando para editar el archivo /etc/timezone con nano:
sudo nano /etc/timezone

En resumen, Django toma la zona horaria configurada en TIME_ZONE como la zona horaria principal para tu aplicación. Cuando almacenas una fecha en la base de datos, se almacena en UTC y se ajusta automáticamente a la zona horaria especificada en TIME_ZONE cuando se recupera y se muestra en tu aplicación. La configuración del sistema operativo generalmente no afecta directamente a cómo Django maneja las fechas en la aplicación, siempre y cuando Django esté configurado correctamente.

Por lo tanto, para asegurarte de que las fechas se almacenan y se muestran correctamente en tu aplicación, debes definir la zona horaria adecuada en la configuración de Django (settings.py) utilizando TIME_ZONE y asegurarte de que la configuración de la base de datos esté en consonancia con esto (generalmente, las bases de datos almacenan fechas en UTC 00:00 por defecto).

Ejemplo practico.

1. Configuración en Django:

En tu archivo settings.py, tienes configurado el timezone de Django de la siguiente manera:

TIME_ZONE = 'America/Cancun'

Esto significa que Django trabajará en el huso horario de Cancún.

2. Configuración en MySQL:

En tu servidor MySQL, la configuración de la zona horaria está configurada en UTC 00:00.

3. Ejemplo de Creación de Registro en Django:

A continuación, vamos a crear un registro en el modelo EstadoArticulo desde el shell de Django:

from tu_app.models import EstadoArticulo
from django.utils import timezone

# Crear un nuevo registro
estado = EstadoArticulo.objects.create(
    nombre='Disponible',
    class_css='verde',
    para_articulo=True,
    color='green',
    created=timezone.now()
)

Nota Cuando insertas un registro en Django usando timezone.now(), este toma la hora y fecha actual en el timezone configurado en tu archivo de configuración de Django (TIME_ZONE). En tu caso es "America/Cancun", que es UTC-5 en horario estándar. Por lo tanto, si inserto el registro a las 17:04 PM en Cancún, en UTC serían las 22:04 (5 horas más tarde).

4. Verificación en MySQL:

Puedes verificar el registro directamente en MySQL utilizando una consulta. Por ejemplo, puedes abrir MySQL y ejecutar:

SELECT * FROM tu_app_estadoarticulo;

Deberías ver el registro que acabas de crear con la fecha y hora en UTC 00:00 en el campo created. Esto es porque MySQL está configurado en UTC. En este caso vemos que es correcto el registro se guardo en UTC 00:00 a las 22:05 (5 horas más tarde) al timezone configurado en django America/Cancun image

Cuando consultas el registro desde MySQL, la base de datos almacena la fecha y hora en formato UTC (sin cambios por la configuración de Django). La hora "2023-09-21 22:04:03.055470" es la representación UTC del registro que se inserto a las 17:04 PM en Cancún. Esto es correcto ya que MySQL almacena las fechas y horas en UTC por defecto para garantizar la consistencia en diferentes zonas horarias.

5. Verificación en Django:

Ahora, volvamos a Django y obtengamos ese registro desde la base de datos y lo pintamos en nuestro template/vista.

estado_recuperado = EstadoArticulo.objects.get(nombre='Disponible')

Cuando recuperas el registro en Django, Django lo convierte automáticamente al timezone configurado en tus ajustes de settings.py de Django (TIME_ZONE). Esto significa que Django está mostrando la fecha y hora en el timezone configurado en tu proyecto, "America/Cancun" en este caso. Entonces, sí, el comportamiento es correcto y consistente con la configuración de Django y MySQL.

image

Si verificamos el campo created en estado_recuperado, notarás que Django automáticamente ha convertido la fecha y hora al huso horario configurado en TIME_ZONE, en settings.py que es 'America/Cancun'. Esto significa que aunque MySQL almacena todo en UTC 00:00, Django se asegura de que las fechas se muestren y manipulen en el huso horario correcto para tu aplicación.

Conclusión

Lo más importante a recordar es que la configuración en MySQL es en UTC 00:00, lo que proporciona una base de tiempo consistente. Luego, en Django, puedes configurar el huso horario según tus necesidades y la aplicación se encargará de las conversiones necesarias al mostrar y manipular fechas y horas. Esto garantiza una gestión precisa de la zona horaria en tu aplicación.