What is Django.utils.timezone?

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.

Syntax

from django.utils import timezone

now = timezone.now()

Code

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)

Explanation

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:

  1. Django will accept naive datetime objects, as long as USE_TZ = True is in the settings.
  2. One needs to first import the concept of timezone into the document. How is this done? It can be done through a library called 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'
  1. 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.

  2. 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"}}
  • If a date is aware and timezone is used, it would look like this: "2021-11-01T13:20:30+03:00"
  • If it is naive, it would like this: "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.

Free Resources