Django
Zonas horarias
Buscar..
Introducción
Las zonas horarias son a menudo una molestia para los desarrolladores. Django ofrece algunas excelentes utilidades a su disposición para facilitar el trabajo con las zonas horarias.
Incluso si su proyecto está operando en una sola zona horaria, sigue siendo una buena práctica almacenar datos como UTC en su base de datos para manejar los casos de ahorro de luz diurna. Si está operando en múltiples zonas horarias, almacenar datos de tiempo como UTC es una necesidad.
Habilitar soporte de zona horaria
Primero es primero, asegúrese de que USE_TZ = True
en su archivo settings.py
. También establezca un valor de zona horaria predeterminado en TIME_ZONE
, como TIME_ZONE='UTC'
. Vea una lista completa de zonas horarias aquí .
Si USE_TZ
es Falso, TIME_ZONE
será la zona horaria que Django usará para almacenar todas las fechas de los datos. Cuando USE_TZ
está habilitado, TIME_ZONE
es la zona horaria predeterminada que Django usará para mostrar los tiempos de las fechas en las plantillas e interpretar los tiempos de los datos ingresados en los formularios.
Con el soporte de zona horaria habilitado, django almacenará los datos de datetime
y datetime
en la base de datos como la zona horaria UTC
Configuración de zonas horarias de sesión
Los objetos datetime.datetime
de Python tienen un atributo tzinfo
que se utiliza para almacenar información de zona horaria. Cuando se establece el atributo, el objeto se considera consciente, cuando el atributo no se establece, se considera un ingenuo.
Para asegurarse de que una zona horaria sea ingenua o consciente, puede usar .is_naive()
y .is_aware()
Si tiene USE_TZ
habilitado en su archivo settings.py
, una datetime
y datetime
tendrá información de zona horaria adjunta siempre que su TIME_ZONE
predeterminado esté configurado en settings.py
Si bien esta zona horaria predeterminada puede ser buena en algunos casos, es probable que no sea suficiente, especialmente si está manejando usuarios en múltiples zonas horarias. Para lograr esto, se debe utilizar middleware.
import pytz
from django.utils import timezone
# make sure you add `TimezoneMiddleware` appropriately in settings.py
class TimezoneMiddleware(object):
"""
Middleware to properly handle the users timezone
"""
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
# make sure they are authenticated so we know we have their tz info.
if request.user.is_authenticated():
# we are getting the users timezone that in this case is stored in
# a user's profile
tz_str = request.user.profile.timezone
timezone.activate(pytz.timezone(tz_str))
# otherwise deactivate and the default time zone will be used anyway
else:
timezone.deactivate()
response = self.get_response(request)
return response
Hay algunas cosas nuevas que están sucediendo. Para obtener más información sobre el middleware y lo que hace, consulte esa parte de la documentación . En __call__
estamos manejando la configuración de los datos de la zona horaria. Al principio, nos aseguramos de que el usuario esté autenticado, para asegurarnos de que tenemos datos de la zona horaria para este usuario. Una vez que sabemos que lo hacemos, activamos la zona horaria para la sesión de los usuarios utilizando timezone.activate()
. Para convertir la cadena de zona horaria que tenemos a algo utilizable por datetime, usamos pytz.timezone(str)
.
Ahora, cuando se accede a los objetos de fecha y hora en plantillas, se convertirán automáticamente del formato 'UTC' de la base de datos a cualquier zona horaria en la que se encuentre el usuario. Simplemente acceda al objeto de fecha y hora y se establecerá su zona horaria, asumiendo que el middleware anterior esté configurado correctamente.
{{ my_datetime_value }}
Si desea un control detallado sobre si se usa la zona horaria del usuario, mire lo siguiente:
{% load tz %}
{% localtime on %}
{# this time will be respect the users time zone #}
{{ your_date_time }}
{% endlocaltime %}
{% localtime off %}
{# this will not respect the users time zone #}
{{ your_date_time }}
{% endlocaltime %}
Tenga en cuenta que este método descrito solo funciona en Django 1.10 y en. Para admitir django desde antes de 1.10, busque en MiddlewareMixin