← All Articles A Product of Kinsa Creative

Use Django's settings.TIME_ZONE to create a time zone aware datetime object

Make a datetime object time zone aware by replacing tzinfo with a pytz.timezone:

import pytz

from datetime import datetime

from django.conf import settings


datetime(2020, 4, 23).replace(tzinfo=pytz.timezone(settings.TIME_ZONE))

A big qualification about replace()

When using replace(), the timezone call isn't aware of the date and so if a timezone offset has changed over time, depending on the date, you might get a wrong offset value. For example, the US/Eastern timezone is -0456 (A full explanation of where -0456 comes from, here.) . A safer method is to call pytz.localize() on the date object:

import pytz

from datetime import datetime

from django.conf import settings


pytz.timezone(settings.TIME_ZONE).localize(datetime(2020, 4, 23))

Passing pytz.timezone() to a datetime object to change its timezone

You can pass a timezone to a date to get the current time in a time zone:

import pytz

from datetime import datetime

from django.conf import settings


datetime.now(pytz.timezone(settings.TIME_ZONE))

Or, get the datetime in another time zone, such as UTC. Here, simply passing pytz.utc rather than querying pytz by a key string as when doing so by passing settings.TIME_ZONE:

import pytz

from datetime import datetime


datetime.now(pytz.utc)

In testing:

import pytz

from datetime import datetime
from mock import patch

from django.conf import settings
from django.test import TestCase


class MyTest(TestCase):
    @patch('django.utils.timezone.now')
    def test_something(self, mock_timezone):
        dt = datetime(2020, 10, 5, 8, 0, 0, tzinfo=pytz.timezone(settings.TIME_ZONE))
        mock_timezone.return_value = dt
        ... some test that calls timezone.now() ...

An easier way

Since Django 1.11, django.utils.timezone.localtime() and django.utils.timezone.localdate() can be used to create a date or datetime object based on settings.TIME_ZONE.

from django.utils import timezone

> timezone.localtime()
... datetime.datetime(2021, 8, 4, 8, 23, 31, 552033, tzinfo=)
> timezone.localdate()
... datetime.date(2021, 8, 4)

Feedback?

Email us at enquiries@kinsa.cc.