Djngo.Utils.Timezone
, also called django.utils.tzinfo
, is a support system within Django that stores data and time information in UTC in the database. It uses the time-zone-aware- datetime objects internally and translates them to the user’s time zone in templates. This can come in very handy when dealing with users in different time zones, as well as when there is daylight saving time.
from django.utils import timezone
now = timezone.now()
So how would this look all together?
import pytz
from django.utils import timezone
class TimezoneMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
tzname = request.session.get('django_timezone')
if tzname:
timezone.activate(pytz.timezone(tzname))
else:
timezone.deactivate()
return self.get_response(request)
Before using this feature and code, you should check whether the object is naive or aware. If the object is calculating the time with timezone, then it is considered aware and set. Otherwise, it is considered naive because it does not have a timezone attached to the object. If it is naive, one would just have local time. Objects that are coming from a database as a datetime object are usually naive. To fix this, one can use timezone. There are many ways that one can use timezone, and we will cover a few of the methods.
This is a checklist to ensure you are set and ready to go:
USE_TZ = True
is in the settings.pytz
. This is a database that allows accurate and cross platform timezone calculations. It includes the following functions:'utc'
'get_fixed_timezone'
'get_default_timezone'
'get_default_timezone_name'
'get_current_timezone'
'get_current_timezone_name'
'activate'
'deactivate'
'override'
'localtime'
'now'
'is_aware'
'is_naive'
'make_aware'
'make_naive'
Then, one can try and use it by writing
now = timezone.now()
to get the current time zone in the user’s zone where rendered.
This last step of receiving the current timezone is different than the default timezone. The default timezone is the one that is defined by the time zone in settings. Therefore if you want to actually get the current timezone of the user instead of just the timezone that the creator used, you should set the current time zone to the user’s actual time zone with the use of activate()
.
activate(settings.TIME_ZONE)
But sometimes it isn’t helpful to receive the timezone as the user’s local time, so there is another options. The tz
template tag allows one to pick the conversion. This tag is the timezone information tag that allows one to still use local time with the tz
tag, which acts very similar to USE_TZ
, but with greater control. For example, to use the tag to get local time could look something like this:
{% load tz %}
{% localtime on %}
{{ value }}
{% endlocaltime %}
{% localtime off %}
{{ value }}
{% endlocaltime %}
Note: One should note that once inside the localtime block, USE_TZ would not be recognized.
One can then change the timezone by substituting timezone into the place where the localtime block sits. To receive the local time in London, it might look something like this:
{% load tz %}
{% timezone "Europe/London" %}
Paris time: {{ value }}
{% endtimezone %}
{% timezone None %}
Server time: {{ value }}
{% endtimezone %}
One can also ask and get the current time zone by merely asking to get the current time zone : get_current_timezone as TIME_ZONE
.
There are some filters that accept both aware and naive datetimes, and by default will convert to default time zone and return aware datetimes. These include localtime, central time, and the ability to use any timezone. These would look as follows:
{% load tz %}
{{ value|localtime }}
{{ value|utc }}
{{value|timezone:"Europe/Paris"}}
"2021-11-01T13:20:30+03:00"
"2021-11-01T13:20:30"
.This is a very helpful support, and should be used even when using only one time zone, as it helps Django perfect the local time model. The one thing to be very careful of is that the datetime objects are aware, and not naive. There will be errors if the objects are unaware, but these can be fixed.