Skip to main content

A Django app providing DB, form, and REST framework fields for zoneinfo and pytz timezone objects.

Project description


CI codecov pypi downloads pypi python support pypi django support

A Django app providing DB, form, and REST framework fields for zoneinfo and pytz timezone objects.

The transition from pytz to zoneinfo

Like Django, this app supports both pytz and zoneinfo objects while the community transitions away from pytz to zoneinfo. All exposed fields and functions that return a timezone object accept an optional boolean kwarg use_pytz.

If not explicitly specified, the default value used for use_pytz matches Django's behavior:

When switching between pytz and zoneinfo, in general a data migration is not needed, as both libraries recognize the same set of strings as valid timezones. Exceptions to that include if your local system has an unusual set of time zones installed, or if you are using the Factory timezone which zoneinfo recognizes but pytz does not.


Database Field

import zoneinfo
import pytz
from django.db import models
from timezone_field import TimeZoneField

class MyModel(models.Model):
    tz1 = TimeZoneField(default="Asia/Dubai")               # defaults supported, in ModelForm renders like "Asia/Dubai"
    tz2 = TimeZoneField(choices_display="WITH_GMT_OFFSET")  # in ModelForm renders like "GMT+04:00 Asia/Dubai"
    tz3 = TimeZoneField(use_pytz=True)                      # returns pytz timezone objects
    tz4 = TimeZoneField(use_pytz=False)                     # returns zoneinfo objects

my_model = MyModel(
    tz2="America/Vancouver",                     # assignment of a string
    tz3=pytz.timezone("America/Vancouver"),      # assignment of a pytz timezone
    tz4=zoneinfo.ZoneInfo("America/Vancouver"),  # assignment of a zoneinfo
my_model.full_clean() # validates against pytz.common_timezones by default       # values stored in DB as strings
my_model.tz3          # value returned as pytz timezone: <DstTzInfo 'America/Vancouver' LMT-1 day, 15:48:00 STD>
my_model.tz4          # value returned as zoneinfo: zoneinfo.ZoneInfo(key='America/Vancouver')

Form Field

from django import forms
from timezone_field import TimeZoneFormField

class MyForm(forms.Form):
    tz1 = TimeZoneFormField()                                   # renders like "Asia/Dubai"
    tz2 = TimeZoneFormField(choices_display="WITH_GMT_OFFSET")  # renders like "GMT+04:00 Asia/Dubai"
    tz3 = TimeZoneFormField(use_pytz=True)                      # returns pytz timezone objects
    tz4 = TimeZoneFormField(use_pytz=False)                     # returns zoneinfo objects

my_form = MyForm({"tz3": "Europe/Berlin", "tz4": "Europe/Berlin"})
my_form.full_clean()         # validates against pytz.common_timezones by default
my_form.cleaned_data["tz3"]  # value returned as pytz timezone: <DstTzInfo 'Europe/Berlin' LMT+0:53:00 STD>
my_form.cleaned_data["tz4"]  # value returned as zoneinfo: zoneinfo.ZoneInfo(key='Europe/Berlin')

REST Framework Serializer Field

from rest_framework import serializers
from timezone_field.rest_framework import TimeZoneSerializerField

class MySerializer(serializers.Serializer):
    tz1 = TimeZoneSerializerField(use_pytz=True)
    tz2 = TimeZoneSerializerField(use_pytz=False)

my_serializer = MySerializer(data={
    "tz1": "America/Argentina/Buenos_Aires",
    "tz2": "America/Argentina/Buenos_Aires",
my_serializer.validated_data["tz1"]  # <DstTzInfo 'America/Argentina/Buenos_Aires' LMT-1 day, 20:06:00 STD>
my_serializer.validated_data["tz2"]  # zoneinfo.ZoneInfo(key='America/Argentina/Buenos_Aires')


Releases are hosted on pypi and can be installed using various python packaging tools.

# with poetry
poetry add django-timezone-field

# with pip
pip install django-timezone-field

Running the tests

From the repository root, with poetry:

poetry install
poetry run pytest


5.0 (2022-02-08)

  • Add support for zoneinfo objects (#79)
  • Add support for django 4.0
  • Remove display_GMT_offset kwarg (use choices_display instead)
  • Drop support for django 3.0, 3.1
  • Drop support for python 3.5, 3.6

4.2.3 (2022-01-13)

  • Fix sdist installs (#78)
  • Officially support python 3.10

4.2.1 (2021-07-07)

  • Reinstate TimeZoneField.default_choices (#76)

4.2 (2021-07-07)

  • Officially support django 3.2, python 3.9
  • Fix bug with field deconstruction (#74)
  • Housekeeping: use poetry, github actions, pytest

4.1.2 (2021-03-17)

  • Avoid NonExistentTimeError during DST transition (#70)

4.1.1 (2020-11-28)

  • Don't import rest_framework from package root (#67)

4.1 (2020-11-28)

  • Add Django REST Framework serializer field
  • Add new choices_display kwarg with supported values WITH_GMT_OFFSET and STANDARD
  • Deprecate display_GMT_offset kwarg

4.0 (2019-12-03)

  • Add support for django 3.0, python 3.8
  • Drop support for django 1.11, 2.0, 2.1, python 2.7, 3.4

3.1 (2019-10-02)

  • Officially support django 2.2 (already worked)
  • Add option to display TZ offsets in form field (#46)

3.0 (2018-09-15)

  • Support django 1.11, 2.0, 2.1
  • Add support for python 3.7
  • Change default human-readable timezone names to exclude underscores (#32 & #37)

2.1 (2018-03-01)

  • Add support for django 1.10, 1.11
  • Add support for python 3.6
  • Add wheel support
  • Support bytes in DB fields (#38 & #39)

2.0 (2016-01-31)

  • Drop support for django 1.7, add support for django 1.9
  • Drop support for python 3.2, 3.3, add support for python 3.5
  • Remove tests from source distribution

1.3 (2015-10-12)

  • Drop support for django 1.6, add support for django 1.8
  • Various bug fixes

1.2 (2015-02-05)

  • For form field, changed default list of accepted timezones from pytz.all_timezones to pytz.common_timezones, to match DB field behavior.

1.1 (2014-10-05)

  • Django 1.7 compatibility
  • Added support for formatting choices kwarg as [[<str>, <str>], ...], in addition to previous format of [[<pytz.timezone>, <str>], ...].
  • Changed default list of accepted timezones from pytz.all_timezones to pytz.common_timezones. If you have timezones in your DB that are in pytz.all_timezones but not in pytz.common_timezones, this is a backward-incompatible change. Old behavior can be restored by specifying choices=[(tz, tz) for tz in pytz.all_timezones] in your model definition.

1.0 (2013-08-04)

  • Initial release as timezone_field.


Originally adapted from Brian Rosner's django-timezones.

Made possible thanks to the work of the contributors.

Project details

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django-timezone-field-5.0.tar.gz (11.8 kB view hashes)

Uploaded source

Built Distribution

Supported by

AWS AWS Cloud computing Datadog Datadog Monitoring Facebook / Instagram Facebook / Instagram PSF Sponsor Fastly Fastly CDN Google Google Object Storage and Download Analytics Huawei Huawei PSF Sponsor Microsoft Microsoft PSF Sponsor NVIDIA NVIDIA PSF Sponsor Pingdom Pingdom Monitoring Salesforce Salesforce PSF Sponsor Sentry Sentry Error logging StatusPage StatusPage Status page