Django
timezone
web development
Python
tutorial

How to set the timezone in Django

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

Timezone configuration in Django affects how datetimes are stored, displayed, and compared across your application. If configuration is inconsistent, scheduled jobs, reports, and user facing timestamps can drift in confusing ways. A robust setup uses UTC for storage, explicit conversion for display, and per user timezone activation when needed.

Core Sections

Configure global timezone settings correctly

Django has two key settings for timezone behavior: TIME_ZONE and USE_TZ. With USE_TZ = True, Django stores aware datetimes in UTC and converts them for presentation. This is the recommended configuration for most modern apps.

python
# settings.py
TIME_ZONE = 'UTC'
USE_TZ = True

If you want a different default display timezone for server side rendering, set TIME_ZONE to a valid IANA name such as America/Toronto, but still keep USE_TZ enabled so storage remains unambiguous.

python
# settings.py
TIME_ZONE = 'America/Toronto'
USE_TZ = True

Work with aware datetimes in application code

Use django.utils.timezone.now() instead of datetime.now() so you always get timezone aware timestamps when USE_TZ is enabled.

python
1from django.utils import timezone
2
3
4def create_audit_record(user):
5    return {
6        'user_id': user.id,
7        'created_at': timezone.now(),
8    }

For conversions, use timezone.localtime when rendering values in templates or API serializers.

python
1from django.utils import timezone
2
3
4def display_time(dt, tz):
5    return timezone.localtime(dt, tz)

This avoids subtle bugs where naive and aware values are mixed in comparisons.

Activate timezone per request for user specific display

If users can choose their preferred timezone, activate it at request scope. A middleware is a clean place for this logic.

python
1# middleware.py
2from zoneinfo import ZoneInfo
3from django.utils import timezone
4
5
6class UserTimezoneMiddleware:
7    def __init__(self, get_response):
8        self.get_response = get_response
9
10    def __call__(self, request):
11        tz_name = getattr(getattr(request, 'user', None), 'timezone', None)
12        if tz_name:
13            timezone.activate(ZoneInfo(tz_name))
14        else:
15            timezone.deactivate()
16
17        return self.get_response(request)

Register middleware in MIDDLEWARE and ensure authenticated user data is available before timezone activation logic runs.

Templates and forms with timezone aware behavior

Django templates automatically localize datetimes when timezone support is active, especially with USE_TZ = True. For forms and API payloads, validate incoming datetime format and decide whether client values are local time or UTC. Be explicit in API docs to avoid ambiguous interpretation.

For background workers using Celery or cron style jobs, keep scheduling logic in UTC and convert only when communicating with users. This keeps execution deterministic even around daylight saving transitions.

Testing timezone behavior

Write tests for boundary moments, including daylight saving changes and midnight crossings. These cases often reveal hidden assumptions.

python
1from django.test import TestCase, override_settings
2from django.utils import timezone
3from zoneinfo import ZoneInfo
4
5
6class TimezoneTests(TestCase):
7    @override_settings(USE_TZ=True, TIME_ZONE='UTC')
8    def test_local_conversion(self):
9        dt = timezone.now()
10        local = timezone.localtime(dt, ZoneInfo('Europe/Paris'))
11        self.assertIsNotNone(local.tzinfo)

Common Pitfalls

  • Setting TIME_ZONE but disabling USE_TZ, then mixing local and UTC assumptions. Keep USE_TZ enabled for reliable storage.
  • Using datetime.now() directly in models and services. Prefer timezone.now() for aware timestamps.
  • Activating user timezone globally rather than per request. Use request scoped activation to avoid cross user leakage.
  • Parsing client datetime strings without explicit timezone contract. Define and enforce API datetime rules.
  • Ignoring daylight saving edge cases in tests. Add boundary tests for transition days.

Summary

  • Use USE_TZ = True and store canonical timestamps in UTC.
  • Use Django timezone utilities for creation and conversion of datetimes.
  • Activate per user timezone at request scope when localized display is required.
  • Keep scheduling and persistence logic timezone safe and explicit.
  • Validate behavior with tests that include DST and boundary scenarios.

Additional implementation notes: verify assumptions under realistic load, keep integration boundaries explicit, and capture edge cases in tests so regressions are easier to detect.


Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.