Django
Fusi orari
Ricerca…
introduzione
I fusi orari sono spesso una seccatura per gli sviluppatori. Django offre alcune ottime utility a tua disposizione per rendere i fusi orari facili da usare.
Anche se il tuo progetto funziona in un singolo fuso orario, è comunque buona norma archiviare i dati come UTC nel tuo database per gestire i casi di ora legale. Se si opera su più fusi orari, la memorizzazione dei dati temporali come UTC è indispensabile.
Abilita supporto fuso orario
Per prima cosa, assicurati che USE_TZ = True
nel file settings.py
. Imposta anche un valore predefinito del fuso orario su TIME_ZONE
come TIME_ZONE='UTC'
. Visualizza l'elenco completo dei fusi orari qui .
Se USE_TZ
è False, TIME_ZONE
sarà il fuso orario che Django utilizzerà per memorizzare tutti i dati. Quando USE_TZ
è abilitato, TIME_ZONE
è il fuso orario predefinito che Django utilizzerà per visualizzare i datetimes nei modelli e per interpretare i dati di data immessi nei moduli.
Con il supporto fuso orario abilitato, django memorizzerà i dati datetime
nel database come il fuso orario UTC
Impostazione dei fusi orari della sessione
Gli oggetti datetime.datetime
di Python hanno un attributo tzinfo
che viene utilizzato per memorizzare le informazioni sul fuso orario. Quando l'attributo è impostato, l'oggetto è considerato Aware, quando l'attributo non è impostato è considerato un Naive.
Per garantire che un fuso orario sia ingenuo o consapevole, puoi utilizzare .is_naive()
e .is_aware()
Se avete USE_TZ
abilitati nel tuo settings.py
file, un datetime
avrà informazioni sul fuso orario collegato ad esso fino a quando il difetto TIME_ZONE
si trova in settings.py
Sebbene questo fuso orario predefinito possa essere buono in alcuni casi, probabilmente non è sufficiente, soprattutto se si gestiscono utenti in più fusi orari. Per ottenere ciò, è necessario utilizzare il 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
Ci sono alcune cose nuove in corso. Per saperne di più sul middleware e su cosa controlla questa parte della documentazione . In __call__
l'impostazione dei dati del fuso orario. Inizialmente ci assicuriamo che l'utente sia autenticato, per assicurarci di avere i dati del fuso orario per questo utente. Quando lo sappiamo, attiviamo il fuso orario per la sessione degli utenti utilizzando timezone.activate()
. Per convertire la stringa del fuso orario abbiamo qualcosa utilizzabile da datetime, usiamo pytz.timezone(str)
.
Ora, quando gli oggetti datetime sono accessibili nei modelli, verranno automaticamente convertiti dal formato "UTC" del database a qualsiasi fuso orario in cui si trova l'utente. Basta accedere all'oggetto datetime e il suo fuso orario verrà impostato assumendo che il middleware precedente sia impostato propriamente.
{{ my_datetime_value }}
Se desideri un controllo a grana fine se viene utilizzato il fuso orario dell'utente, dai un'occhiata a quanto segue:
{% 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 %}
Nota, questo metodo descritto funziona solo in Django 1.10 e oltre. Per supportare django da precedente a 1.10, guarda a MiddlewareMixin