Package: django-timezone-field
django-timezone-fieldA Django app providing DB, form, and REST framework fields forzoneinfoandpytztimezone
objects.The transition frompytztozoneinfoLike Django, this app supports bothpytzandzoneinfoobjects while the community transitions away frompytztozoneinfo. All exposed fields and functions that return a timezone object accept an optional boolean kwarguse_pytz.If not explicitly specified, the default value used foruse_pytzmatches Django's behavior:Django <= 3.X:use_pytzdefaults toTrueDjango == 4.X:use_pytzdefaults to the value ofdjango.conf.settings.USE_DEPRECATED_PYTZ,
which itself defaults toFalseDjango >= 5.X: django plans todrop support forpytzaltogether,
and this app will likely do the same.Note that this app doesnotdeclarepytzto be a dependency, so if you're using this app withuse_pytz=True, you'll need
to ensurepytzis included in the environment yourself.Differences in recognized timezones betweenpytzandzoneinfopytzandzoneinfosearch for timezone data differently.pytzbundles and searches within its own copy of theIANA timezone DBzoneinfofirst searches the local system's timezone DB for a match. If no match is found, it then searches within
thetzdatapackageif it is installed. Thetzdatapackage contains a copy of
the IANA timezone DB.If the local system's timezone DB doesn't cover the entire IANA timezone DB and thetzdatapackage is not installed,
you may run across errors likeZoneInfoNotFoundError: 'No time zone found with key Pacific/Kanton'for seemingly valid
timezones when transitioning frompytztozoneinfo. The easy fix is to addtzdatato your project withpoetry add tzdataorpip install tzdata.Assuming you have thetzdatapackage installed if needed, nodata migrationshould be necessary when
switching frompytztozoneinfo.ExamplesDatabase Fieldimportzoneinfoimportpytzfromdjango.dbimportmodelsfromtimezone_fieldimportTimeZoneFieldclassMyModel(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 objectstz4=TimeZoneField(use_pytz=False)# returns zoneinfo objectsmy_model=MyModel(tz2="America/Vancouver",# assignment of a stringtz3=pytz.timezone("America/Vancouver"),# assignment of a pytz timezonetz4=zoneinfo.ZoneInfo("America/Vancouver"),# assignment of a zoneinfo)my_model.full_clean()# validates against pytz.common_timezones by defaultmy_model.save()# values stored in DB as stringsmy_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 Fieldfromdjangoimportformsfromtimezone_fieldimportTimeZoneFormFieldclassMyForm(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 objectstz4=TimeZoneFormField(use_pytz=False)# returns zoneinfo objectsmy_form=MyForm({"tz3":"Europe/Berlin","tz4":"Europe/Berlin"})my_form.full_clean()# validates against pytz.common_timezones by defaultmy_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 Fieldfromrest_frameworkimportserializersfromtimezone_field.rest_frameworkimportTimeZoneSerializerFieldclassMySerializer(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.is_valid()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')InstallationReleases are hosted onpypiand can be installed using various
python packaging tools.# with poetrypoetryadddjango-timezone-field# with pippipinstalldjango-timezone-fieldRunning the testsFrom the repository root, withpoetry:poetryinstall
poetryrunpytestChangelog6.1.0 (2023-11-25)Add support for django 5.0Add support for python 3.12Fix issue withFactorytimezone on some BSD systems (#114)6.0.1 (2023-09-07)Use correct default backend when running with django 3.X (#109)6.0 (2023-08-20)BREAKING:pytzremoved from dependencies. If you use this package withuse_pytz=True, you'll need to installpytzyourself.Drop support for django 2.2Drop support for python 3.75.1 (2023-06-18)Add django as a dependency of this package, with correct version constraints
(#90)Add support for django 4.1, 4.2Add support for python 3.115.0 (2022-02-08)Add support forzoneinfoobjects (#79)Add support for django 4.0Removetimezone_field.utils.add_gmt_offset_to_choices,display_GMT_offsetkwarg (usechoices_displayinstead)Drop support for django 3.0, 3.1Drop support for python 3.5, 3.64.2.3 (2022-01-13)Fix sdist installs (#78)Officially support python 3.104.2.1 (2021-07-07)ReinstateTimeZoneField.default_choices(#76)4.2 (2021-07-07)Officially support django 3.2, python 3.9Fix bug with field deconstruction (#74)Housekeeping: use poetry, github actions, pytest4.1.2 (2021-03-17)AvoidNonExistentTimeErrorduring DST transition (#70)4.1.1 (2020-11-28)Don't importrest_frameworkfrom package root (#67)4.1 (2020-11-28)Add Django REST Framework serializer fieldAdd newchoices_displaykwarg with supported valuesWITH_GMT_OFFSETandSTANDARDDeprecatedisplay_GMT_offsetkwarg4.0 (2019-12-03)Add support for django 3.0, python 3.8Drop support for django 1.11, 2.0, 2.1, python 2.7, 3.43.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.1Add support for python 3.7Change default human-readable timezone names to exclude underscores
(#32&#37)2.1 (2018-03-01)Add support for django 1.10, 1.11Add support for python 3.6Add wheel supportSupport bytes in DB fields (#38&#39)2.0 (2016-01-31)Drop support for django 1.7, add support for django 1.9Drop support for python 3.2, 3.3, add support for python 3.5Remove tests from source distribution1.3 (2015-10-12)Drop support for django 1.6, add support for django 1.8Variousbug fixes1.2 (2015-02-05)For form field, changed default list of accepted timezones frompytz.all_timezonestopytz.common_timezones, to
match DB field behavior.1.1 (2014-10-05)Django 1.7 compatibilityAdded support for formattingchoiceskwarg as[[<str>, <str>], ...], in addition to previous format of[[<pytz.timezone>, <str>], ...].Changed default list of accepted timezones frompytz.all_timezonestopytz.common_timezones. If you have timezones
in your DB that are inpytz.all_timezonesbut not inpytz.common_timezones, this is a backward-incompatible
change. Old behavior can be restored by specifyingchoices=[(tz, tz) for tz in pytz.all_timezones]in your model
definition.1.0 (2013-08-04)Initial release astimezone_field.CreditsOriginally adapted fromBrian Rosner's django-timezones.Made possible thanks to the work of thecontributors.