summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorAymeric Augustin <aymeric.augustin@m4x.org>2011-11-18 13:01:06 +0000
committerAymeric Augustin <aymeric.augustin@m4x.org>2011-11-18 13:01:06 +0000
commit9b1cb755a28f020e27d4268c214b25315d4de42e (patch)
tree2ff0827176f0eb49defa4ce7ce10164f2fc26e86 /docs
parent01f70349c9ef23d6751437dcd57d2efc193b2661 (diff)
Added support for time zones. Thanks Luke Plant for the review. Fixed #2626.
For more information on this project, see this thread: http://groups.google.com/group/django-developers/browse_thread/thread/cf0423bbb85b1bbf git-svn-id: http://code.djangoproject.com/svn/django/trunk@17106 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'docs')
-rw-r--r--docs/howto/custom-template-tags.txt25
-rw-r--r--docs/ref/models/querysets.txt13
-rw-r--r--docs/ref/settings.txt54
-rw-r--r--docs/ref/templates/builtins.txt63
-rw-r--r--docs/ref/utils.txt125
-rw-r--r--docs/releases/1.4.txt53
-rw-r--r--docs/topics/cache.txt4
-rw-r--r--docs/topics/i18n/index.txt10
-rw-r--r--docs/topics/i18n/timezones.txt429
9 files changed, 734 insertions, 42 deletions
diff --git a/docs/howto/custom-template-tags.txt b/docs/howto/custom-template-tags.txt
index 6b2355e8d0..0b962f8863 100644
--- a/docs/howto/custom-template-tags.txt
+++ b/docs/howto/custom-template-tags.txt
@@ -347,6 +347,31 @@ function; this syntax is deprecated.
return mark_safe(result)
initial_letter_filter.needs_autoescape = True
+.. _filters-timezones:
+
+Filters and time zones
+~~~~~~~~~~~~~~~~~~~~~~
+
+.. versionadded:: 1.4
+
+If you write a custom filter that operates on :class:`~datetime.datetime`
+objects, you'll usually register it with the ``expects_localtime`` flag set to
+``True``:
+
+.. code-block:: python
+
+ @register.filter(expects_localtime=True)
+ def businesshours(value):
+ try:
+ return 9 <= value.hour < 17
+ except AttributeError:
+ return ''
+
+When this flag is set, if the first argument to your filter is a time zone
+aware datetime, Django will convert it to the current time zone before passing
+to your filter when appropriate, according to :ref:`rules for time zones
+conversions in templates <time-zones-in-templates>`.
+
Writing custom template tags
----------------------------
diff --git a/docs/ref/models/querysets.txt b/docs/ref/models/querysets.txt
index 68da9c7343..9736d94838 100644
--- a/docs/ref/models/querysets.txt
+++ b/docs/ref/models/querysets.txt
@@ -546,6 +546,12 @@ Examples::
>>> Entry.objects.filter(headline__contains='Lennon').dates('pub_date', 'day')
[datetime.datetime(2005, 3, 20)]
+.. warning::
+
+ When :doc:`time zone support </topics/i18n/timezones>` is enabled, Django
+ uses UTC in the database connection, which means the aggregation is
+ performed in UTC. This is a known limitation of the current implementation.
+
none
~~~~
@@ -1953,6 +1959,13 @@ Note this will match any record with a ``pub_date`` that falls on a Monday (day
2 of the week), regardless of the month or year in which it occurs. Week days
are indexed with day 1 being Sunday and day 7 being Saturday.
+.. warning::
+
+ When :doc:`time zone support </topics/i18n/timezones>` is enabled, Django
+ uses UTC in the database connection, which means the ``year``, ``month``,
+ ``day`` and ``week_day`` lookups are performed in UTC. This is a known
+ limitation of the current implementation.
+
.. fieldlookup:: isnull
isnull
diff --git a/docs/ref/settings.txt b/docs/ref/settings.txt
index 20366e353d..0d91f16821 100644
--- a/docs/ref/settings.txt
+++ b/docs/ref/settings.txt
@@ -1810,6 +1810,7 @@ Default::
"django.core.context_processors.i18n",
"django.core.context_processors.media",
"django.core.context_processors.static",
+ "django.core.context_processors.tz",
"django.contrib.messages.context_processors.messages")
A tuple of callables that are used to populate the context in ``RequestContext``.
@@ -1830,6 +1831,10 @@ of items to be merged into the context.
The ``django.core.context_processors.static`` context processor
was added in this release.
+.. versionadded:: 1.4
+ The ``django.core.context_processors.tz`` context processor
+ was added in this release.
+
.. setting:: TEMPLATE_DEBUG
TEMPLATE_DEBUG
@@ -1971,6 +1976,9 @@ Default: ``'America/Chicago'``
.. versionchanged:: 1.2
``None`` was added as an allowed value.
+.. versionchanged:: 1.4
+ The meaning of this setting now depends on the value of :setting:`USE_TZ`.
+
A string representing the time zone for this installation, or
``None``. `See available choices`_. (Note that list of available
choices lists more than one on the same line; you'll want to use just
@@ -1978,16 +1986,19 @@ one of the choices for a given time zone. For instance, one line says
``'Europe/London GB GB-Eire'``, but you should use the first bit of
that -- ``'Europe/London'`` -- as your :setting:`TIME_ZONE` setting.)
-Note that this is the time zone to which Django will convert all
-dates/times -- not necessarily the timezone of the server. For
-example, one server may serve multiple Django-powered sites, each with
-a separate time-zone setting.
+Note that this isn't necessarily the timezone of the server. For example, one
+server may serve multiple Django-powered sites, each with a separate time zone
+setting.
+
+When :setting:`USE_TZ` is ``False``, this is the time zone in which Django will
+store all datetimes. When :setting:`USE_TZ` is ``True``, this is the default
+time zone that Django will use to display datetimes in templates and to
+interpret datetimes entered in forms.
-Normally, Django sets the ``os.environ['TZ']`` variable to the time
-zone you specify in the :setting:`TIME_ZONE` setting. Thus, all your views
-and models will automatically operate in the correct time zone.
-However, Django won't set the ``TZ`` environment variable under the
-following conditions:
+Django sets the ``os.environ['TZ']`` variable to the time zone you specify in
+the :setting:`TIME_ZONE` setting. Thus, all your views and models will
+automatically operate in this time zone. However, Django won't set the ``TZ``
+environment variable under the following conditions:
* If you're using the manual configuration option as described in
:ref:`manually configuring settings
@@ -2004,7 +2015,6 @@ to ensure your processes are running in the correct environment.
environment. If you're running Django on Windows, this variable
must be set to match the system timezone.
-
.. _See available choices: http://www.postgresql.org/docs/8.1/static/datetime-keywords.html#DATETIME-TIMEZONE-SET-TABLE
.. setting:: URL_VALIDATOR_USER_AGENT
@@ -2043,7 +2053,7 @@ This provides an easy way to turn it off, for performance. If this is set to
``False``, Django will make some optimizations so as not to load the
translation machinery.
-See also :setting:`USE_L10N`
+See also :setting:`LANGUAGE_CODE`, :setting:`USE_L10N` and :setting:`USE_TZ`.
.. setting:: USE_L10N
@@ -2058,7 +2068,7 @@ A boolean that specifies if localized formatting of data will be enabled by
default or not. If this is set to ``True``, e.g. Django will display numbers and
dates using the format of the current locale.
-See also :setting:`USE_I18N` and :setting:`LANGUAGE_CODE`
+See also :setting:`LANGUAGE_CODE`, :setting:`USE_I18N` and :setting:`USE_TZ`.
.. note::
@@ -2082,6 +2092,26 @@ When :setting:`USE_L10N` is set to ``True`` and if this is also set to
See also :setting:`DECIMAL_SEPARATOR`, :setting:`NUMBER_GROUPING` and
:setting:`THOUSAND_SEPARATOR`.
+.. setting:: USE_TZ
+
+USE_TZ
+------
+
+.. versionadded:: 1.4
+
+Default: ``False``
+
+A boolean that specifies if datetimes will be timezone-aware by default or not.
+If this is set to ``True``, Django will use timezone-aware datetimes internally.
+Otherwise, Django will use naive datetimes in local time.
+
+See also :setting:`TIME_ZONE`, :setting:`USE_I18N` and :setting:`USE_L10N`.
+
+.. note::
+ The default :file:`settings.py` file created by
+ :djadmin:`django-admin.py startproject <startproject>` includes
+ ``USE_TZ = True`` for convenience.
+
.. setting:: USE_X_FORWARDED_HOST
USE_X_FORWARDED_HOST
diff --git a/docs/ref/templates/builtins.txt b/docs/ref/templates/builtins.txt
index 7b305746ab..695a21296b 100644
--- a/docs/ref/templates/builtins.txt
+++ b/docs/ref/templates/builtins.txt
@@ -2318,8 +2318,45 @@ Value Argument Outputs
if no mapping for None is given)
========== ====================== ==================================
-Other tags and filter libraries
--------------------------------
+Internationalization tags and filters
+-------------------------------------
+
+Django provides template tags and filters to control each aspect of
+`internationalization </topics/i18n/index>`_ in templates. They allow for
+granular control of translations, formatting, and time zone conversions.
+
+i18n
+^^^^
+
+This library allows specifying translatable text in templates.
+To enable it, set :setting:`USE_I18N` to ``True``, then load it with
+``{% load i18n %}``.
+
+See :ref:`specifying-translation-strings-in-template-code`.
+
+l10n
+^^^^
+
+This library provides control over the localization of values in templates.
+You only need to load the library using ``{% load l10n %}``, but you'll often
+set :setting:`USE_L10N` to ``True`` so that localization is active by default.
+
+See :ref:`topic-l10n-templates`.
+
+tz
+^^
+
+.. versionadded:: 1.4
+
+This library provides control over time zone conversions in templates.
+Like ``l10n``, you only need to load the library using ``{% load tz %}``,
+but you'll usually also set :setting:`USE_TZ` to ``True`` so that conversion
+to local time happens by default.
+
+See :ref:`time-zones-in-templates`.
+
+Other tags and filters libraries
+--------------------------------
Django comes with a couple of other template-tag libraries that you have to
enable explicitly in your :setting:`INSTALLED_APPS` setting and enable in your
@@ -2348,28 +2385,6 @@ django.contrib.webdesign
A collection of template tags that can be useful while designing a Web site,
such as a generator of Lorem Ipsum text. See :doc:`/ref/contrib/webdesign`.
-i18n
-^^^^
-
-Provides a couple of templatetags that allow specifying translatable text in
-Django templates. It is slightly different from the libraries described
-above because you don't need to add any application to the
-:setting:`INSTALLED_APPS` setting but rather set :setting:`USE_I18N` to True,
-then loading it with ``{% load i18n %}``.
-
-See :ref:`specifying-translation-strings-in-template-code`.
-
-l10n
-^^^^
-
-Provides a couple of templatetags that allow control over the localization of
-values in Django templates. It is slightly different from the libraries
-described above because you don't need to add any application to the
-:setting:`INSTALLED_APPS`; you only need to load the library using
-``{% load l10n %}``.
-
-See :ref:`topic-l10n-templates`.
-
static
^^^^^^
diff --git a/docs/ref/utils.txt b/docs/ref/utils.txt
index 0d6e9c6b61..9a9adba0d8 100644
--- a/docs/ref/utils.txt
+++ b/docs/ref/utils.txt
@@ -131,6 +131,41 @@ results. Instead do::
SortedDict([('b', 1), ('a', 2), ('c', 3)])
+``django.utils.dateparse``
+==========================
+
+.. versionadded:: 1.4
+
+.. module:: django.utils.dateparse
+ :synopsis: Functions to parse datetime objects.
+
+The functions defined in this module share the following properties:
+
+- They raise :exc:`ValueError` if their input is well formatted but isn't a
+ valid date or time.
+- They return ``None`` if it isn't well formatted at all.
+- They accept up to picosecond resolution in input, but they truncate it to
+ microseconds, since that's what Python supports.
+
+.. function:: parse_date(value)
+
+ Parses a string and returns a :class:`datetime.date`.
+
+.. function:: parse_time(value)
+
+ Parses a string and returns a :class:`datetime.time`.
+
+ UTC offsets aren't supported; if ``value`` describes one, the result is
+ ``None``.
+
+.. function:: parse_datetime(value)
+
+ Parses a string and returns a :class:`datetime.datetime`.
+
+ UTC offsets are supported; if ``value`` describes one, the result's
+ ``tzinfo`` attribute is a :class:`~django.utils.tzinfo.FixedOffset`
+ instance.
+
``django.utils.encoding``
=========================
@@ -573,6 +608,96 @@ For a complete discussion on the usage of the following see the
so by translating the Django translation tags into standard gettext function
invocations.
+.. _time-zone-selection-functions:
+
+``django.utils.timezone``
+=========================
+
+.. versionadded:: 1.4
+
+.. module:: django.utils.timezone
+ :synopsis: Timezone support.
+
+.. data:: utc
+
+ :class:`~datetime.tzinfo` instance that represents UTC.
+
+.. function:: get_default_timezone()
+
+ Returns a :class:`~datetime.tzinfo` instance that represents the
+ :ref:`default time zone <default-current-time-zone>`.
+
+.. function:: get_default_timezone_name()
+
+ Returns the name of the :ref:`default time zone
+ <default-current-time-zone>`.
+
+.. function:: get_current_timezone()
+
+ Returns a :class:`~datetime.tzinfo` instance that represents the
+ :ref:`current time zone <default-current-time-zone>`.
+
+.. function:: get_current_timezone_name()
+
+ Returns the name of the :ref:`current time zone
+ <default-current-time-zone>`.
+
+.. function:: activate(timezone)
+
+ Sets the :ref:`current time zone <default-current-time-zone>`. The
+ ``timezone`` argument must be an instance of a :class:`~datetime.tzinfo`
+ subclass or, if pytz_ is available, a time zone name.
+
+.. function:: deactivate()
+
+ Unsets the :ref:`current time zone <default-current-time-zone>`.
+
+.. function:: override(timezone)
+
+ This is a Python context manager that sets the :ref:`current time zone
+ <default-current-time-zone>` on entry with :func:`activate()`, and restores
+ the previously active time zone on exit. If the ``timezone`` argument is
+ ``None``, the :ref:`current time zone <default-current-time-zone>` is unset
+ on entry with :func:`deactivate()` instead.
+
+.. function:: aslocaltime(value, use_tz=None)
+
+ This function is used by the template engine to convert datetimes to local
+ time where appropriate.
+
+.. function:: now()
+
+ Returns an aware or naive :class:`~datetime.datetime` that represents the
+ current point in time when :setting:`USE_TZ` is ``True`` or ``False``
+ respectively.
+
+.. function:: is_aware(value)
+
+ Returns ``True`` if ``value`` is aware, ``False`` if it is naive. This
+ function assumes that ``value`` is a :class:`~datetime.datetime`.
+
+.. function:: is_naive(value)
+
+ Returns ``True`` if ``value`` is naive, ``False`` if it is aware. This
+ function assumes that ``value`` is a :class:`~datetime.datetime`.
+
+.. function:: make_aware(value, timezone)
+
+ Returns an aware :class:`~datetime.datetime` that represents the same
+ point in time as ``value`` in ``timezone``, ``value`` being a naive
+ :class:`~datetime.datetime`.
+
+ This function can raise an exception if ``value`` doesn't exist or is
+ ambiguous because of DST transitions.
+
+.. function:: make_naive(value, timezone)
+
+ Returns an naive :class:`~datetime.datetime` that represents in
+ ``timezone`` the same point in time as ``value``, ``value`` being an
+ aware :class:`~datetime.datetime`
+
+.. _pytz: http://pytz.sourceforge.net/
+
``django.utils.tzinfo``
=======================
diff --git a/docs/releases/1.4.txt b/docs/releases/1.4.txt
index 49284fb90b..46527da581 100644
--- a/docs/releases/1.4.txt
+++ b/docs/releases/1.4.txt
@@ -409,7 +409,6 @@ If the same code is imported inconsistently (some places with the project
prefix, some places without it), the imports will need to be cleaned up when
switching to the new ``manage.py``.
-
Improved WSGI support
~~~~~~~~~~~~~~~~~~~~~
@@ -427,6 +426,25 @@ callable :djadmin:`runserver` uses.
(The :djadmin:`runfcgi` management command also internally wraps the WSGI
callable configured via :setting:`WSGI_APPLICATION`.)
+Support for time zones
+~~~~~~~~~~~~~~~~~~~~~~
+
+Django 1.4 adds :ref:`support for time zones <time-zones>`. When it's enabled,
+Django stores date and time information in UTC in the database, uses time
+zone-aware datetime objects internally, and translates them to the end user's
+time zone in templates and forms.
+
+Reasons for using this feature include:
+
+- Customizing date and time display for users around the world.
+- Storing datetimes in UTC for database portability and interoperability.
+ (This argument doesn't apply to PostgreSQL, because it already stores
+ timestamps with time zone information in Django 1.3.)
+- Avoiding data corruption problems around DST transitions.
+
+Time zone support in enabled by default in new projects created with
+:djadmin:`startproject`. If you want to use this feature in an existing
+project, there is a :ref:`migration guide <time-zones-migration-guide>`.
Minor features
~~~~~~~~~~~~~~
@@ -616,6 +634,39 @@ immediately raise a 404. Additionally redirects returned by flatpages are now
permanent (301 status code) to match the behavior of the
:class:`~django.middleware.common.CommonMiddleware`.
+Serialization of :class:`~datetime.datetime` and :class:`~datetime.time`
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+As a consequence of time zone support, and according to the ECMA-262
+specification, some changes were made to the JSON serializer:
+
+- It includes the time zone for aware datetime objects. It raises an exception
+ for aware time objects.
+- It includes milliseconds for datetime and time objects. There is still
+ some precision loss, because Python stores microseconds (6 digits) and JSON
+ only supports milliseconds (3 digits). However, it's better than discarding
+ microseconds entirely.
+
+The XML serializer was also changed to use ISO8601 for datetimes. The letter
+``T`` is used to separate the date part from the time part, instead of a
+space. Time zone information is included in the ``[+-]HH:MM`` format.
+
+The serializers will dump datetimes in fixtures with these new formats. They
+can still load fixtures that use the old format.
+
+``supports_timezone`` changed to ``False`` for SQLite
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The database feature ``supports_timezone`` used to be ``True`` for SQLite.
+Indeed, if you saved an aware datetime object, SQLite stored a string that
+included an UTC offset. However, this offset was ignored when loading the value
+back from the database, which could corrupt the data.
+
+In the context of time zone support, this flag was changed to ``False``, and
+datetimes are now stored without time zone information in SQLite. When
+:setting:`USE_TZ` is ``False``, if you attempt to save an aware datetime
+object, Django raises an exception.
+
`COMMENTS_BANNED_USERS_GROUP` setting
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/docs/topics/cache.txt b/docs/topics/cache.txt
index a3aac74b76..99d764b60d 100644
--- a/docs/topics/cache.txt
+++ b/docs/topics/cache.txt
@@ -502,7 +502,9 @@ cache multilingual sites without having to create the cache key yourself.
.. versionchanged:: 1.4
-This also happens when :setting:`USE_L10N` is set to ``True``.
+Cache keys also include the active :term:`language <language code>` when
+:setting:`USE_L10N` is set to ``True`` and the :ref:`current time zone
+<default-current-time-zone>` when :setting:`USE_TZ` is set to ``True``.
__ `Controlling cache: Using other headers`_
diff --git a/docs/topics/i18n/index.txt b/docs/topics/i18n/index.txt
index 4e2c9c345c..25ec8392de 100644
--- a/docs/topics/i18n/index.txt
+++ b/docs/topics/i18n/index.txt
@@ -8,6 +8,7 @@ Internationalization and localization
translation
formatting
+ timezones
Overview
========
@@ -17,8 +18,8 @@ application to offer its content in languages and formats tailored to the
audience.
Django has full support for :doc:`translation of text
-</topics/i18n/translation>` and :doc:`formatting of dates, times and numbers
-</topics/i18n/formatting>`.
+</topics/i18n/translation>`, :doc:`formatting of dates, times and numbers
+</topics/i18n/formatting>`, and :doc:`time zones </topics/i18n/timezones>`.
Essentially, Django does two things:
@@ -27,8 +28,9 @@ Essentially, Django does two things:
* It uses these hooks to localize Web apps for particular users according to
their preferences.
-Obviously, translation depends on the target language. Formatting usually
-depends on the target country.
+Obviously, translation depends on the target language, and formatting usually
+depends on the target country. These informations are provided by browsers in
+the ``Accept-Language`` header. However, the time zone isn't readily available.
Definitions
===========
diff --git a/docs/topics/i18n/timezones.txt b/docs/topics/i18n/timezones.txt
new file mode 100644
index 0000000000..41e8380acc
--- /dev/null
+++ b/docs/topics/i18n/timezones.txt
@@ -0,0 +1,429 @@
+.. _time-zones:
+
+==========
+Time zones
+==========
+
+.. versionadded:: 1.4
+
+Overview
+========
+
+When support for time zones is enabled, Django stores date and time
+information in UTC in the database, uses time zone-aware datetime objects
+internally, and translates them to the end user's time zone in templates and
+forms.
+
+This is handy if your users live in more than one time zone and you want to
+display date and time information according to each user's wall clock. Even if
+your website is available in only one time zone, it's still a good practice to
+store data in UTC in your database. Here is why.
+
+Many countries have a system of daylight saving time (DST), where clocks are
+moved forwards in spring and backwards in autumn. If you're working in local
+time, you're likely to encounter errors twice a year, when the transitions
+happen. pytz' docs discuss `these issues`_ in greater detail. It probably
+doesn't matter for your blog, but it's more annoying if you over-bill or
+under-bill your customers by one hour, twice a year, every year. The solution
+to this problem is to use UTC in the code and local time only when
+interacting with end users.
+
+Time zone support is disabled by default. To enable it, set :setting:`USE_TZ =
+True <USE_TZ>` in your settings file. Installing pytz_ is highly recommended,
+but not mandatory.
+
+.. note::
+
+ The default :file:`settings.py` file created by :djadmin:`django-admin.py
+ startproject <startproject>` includes :setting:`USE_TZ = True <USE_TZ>`
+ for convenience.
+
+.. note::
+
+ There is also an independent but related :setting:`USE_L10N` setting that
+ controls if Django should activate format localization. See
+ :doc:`/topics/i18n/formatting` for more details.
+
+Concepts
+========
+
+Naive and aware datetime objects
+--------------------------------
+
+Python's :class:`datetime.datetime` objects have a ``tzinfo`` attribute that
+can be used to store time zone information, represented as an instance of a
+subclass of :class:`datetime.tzinfo`. When this attribute is set and describes
+an offset, a datetime object is **aware**; otherwise, it's **naive**.
+
+You can use :func:`~django.utils.timezone.is_aware` and
+:func:`~django.utils.timezone.is_naive` to determine if datetimes are aware or
+naive.
+
+When time zone support is disabled, Django uses naive datetime objects in local
+time. This is simple and sufficient for many use cases. In this mode, to obtain
+the current time, you would write::
+
+ import datetime
+
+ now = datetime.datetime.now()
+
+When time zone support is enabled, Django uses time zone aware datetime
+objects. If your code creates datetime objects, they should be aware too. In
+this mode, the example above becomes::
+
+ import datetime
+ from django.utils.timezone import utc
+
+ now = datetime.datetime.utcnow().replace(tzinfo=utc)
+
+.. note::
+
+ :mod:`django.utils.timezone` provides a
+ :func:`~django.utils.timezone.now()` function that returns a naive or
+ aware datetime object according to the value of :setting:`USE_TZ`.
+
+.. warning::
+
+ Dealing with aware datetime objects isn't always intuitive. For instance,
+ the ``tzinfo`` argument of the standard datetime constructor doesn't work
+ reliably for time zones with DST. Using UTC is generally safe; if you're
+ using other time zones, you should review `pytz' documentation <pytz>`_
+ carefully.
+
+.. note::
+
+ Python's :class:`datetime.time` objects also feature a ``tzinfo``
+ attribute, and PostgreSQL has a matching ``time with time zone`` type.
+ However, as PostgreSQL's docs put it, this type "exhibits properties which
+ lead to questionable usefulness".
+
+ Django only supports naive time objects and will raise an exception if you
+ attempt to save an aware time object.
+
+.. _naive-datetime-objects:
+
+Interpretation of naive datetime objects
+----------------------------------------
+
+When :setting:`USE_TZ` is ``True``, Django still accepts naive datetime
+objects, in order to preserve backwards-compatibility. It attempts to make them
+aware by interpreting them in the :ref:`default time zone
+<default-current-time-zone>`.
+
+Unfortunately, during DST transitions, some datetimes don't exist or are
+ambiguous. In such situations, pytz_ raises an exception. Other
+:class:`~datetime.tzinfo` implementations, such as the local time zone used as
+a fallback when pytz_ isn't installed, may raise an exception or return
+inaccurate results. That's why you should always create aware datetime objects
+when time zone support is enabled.
+
+In practice, this is rarely an issue. Django gives you aware datetime objects
+in the models and forms, and most often, new datetime objects are created from
+existing ones through :class:`~datetime.timedelta` arithmetic. The only
+datetime that's often created in application code is the current time, and
+:func:`timezone.now() <django.utils.timezone.now>` automatically does the
+right thing.
+
+.. _default-current-time-zone:
+
+Default time zone and current time zone
+---------------------------------------
+
+The **default time zone** is the time zone defined by the :setting:`TIME_ZONE`
+setting.
+
+When pytz_ is available, Django loads the definition of the default time zone
+from the `tz database`_. This is the most accurate solution. Otherwise, it
+relies on the difference between local time and UTC, as reported by the
+operating system, to compute conversions. This is less reliable, especially
+around DST transitions.
+
+The **current time zone** is the time zone that's used for rendering.
+
+You should set it to the end user's actual time zone with
+:func:`~django.utils.timezone.activate`. Otherwise, the default time zone is
+used.
+
+.. note::
+
+ As explained in the documentation of :setting:`TIME_ZONE`, Django sets
+ environment variables so that its process runs in the default time zone.
+ This happens regardless of the value of :setting:`USE_TZ` and of the
+ current time zone.
+
+ When :setting:`USE_TZ` is ``True``, this is useful to preserve
+ backwards-compatibility with applications that still rely on local time.
+ However, :ref:`as explained above <naive-datetime-objects>`, this isn't
+ entirely reliable, and you should always work with aware datetimes in UTC
+ in your own code. For instance, use
+ :meth:`~datetime.datetime.utcfromtimestamp` instead of
+ :meth:`~datetime.datetime.fromtimestamp` -- and don't forget to set
+ ``tzinfo`` to :data:`~django.utils.timezone.utc`.
+
+Selecting the current time zone
+-------------------------------
+
+The current time zone is the equivalent of the current :term:`locale <locale
+name>` for translations. However, there's no equivalent of the
+``Accept-Language`` HTTP header that Django could use to determine the user's
+time zone automatically. Instead, Django provides :ref:`time zone selection
+functions <time-zone-selection-functions>`. Use them to build the time zone
+selection logic that makes sense for you.
+
+Most websites who care about time zones just ask users in which time zone they
+live and store this information in the user's profile. For anonymous users,
+they use the time zone of their primary audience or UTC. pytz_ provides
+helpers, like a list of time zones per country, that you can use to pre-select
+the most likely choices.
+
+Here's an example that stores the current timezone in the session. (It skips
+error handling entirely for the sake of simplicity.)
+
+Add the following middleware to :setting:`MIDDLEWARE_CLASSES`::
+
+ from django.utils import timezone
+
+ class TimezoneMiddleware(object):
+ def process_request(self, request):
+ tz = request.session.get('django_timezone')
+ if tz:
+ timezone.activate(tz)
+
+Create a view that can set the current timezone::
+
+ import pytz
+ from django.shortcuts import redirect, render
+
+ def set_timezone(request):
+ if request.method == 'POST':
+ request.session[session_key] = pytz.timezone(request.POST['timezone'])
+ return redirect('/')
+ else:
+ return render(request, 'template.html', {'timezones': pytz.common_timezones})
+
+Include in :file:`template.html` a form that will ``POST`` to this view:
+
+.. code-block:: html+django
+
+ {% load tz %}{% load url from future %}
+ <form action="{% url 'set_timezone' %}" method="POST">
+ {% csrf_token %}
+ <label for="timezone">Time zone:</label>
+ <select name="timezone">
+ {% for tz in timezones %}
+ <option value="{{ tz }}"{% if tz == TIME_ZONE %} selected="selected"{% endif %}>{{ tz }}</option>
+ {% endfor %}
+ </select>
+ <input type="submit" value="Set" />
+ </form>
+
+Time zone aware input in forms
+==============================
+
+When you enable time zone support, Django interprets datetimes entered in
+forms in the :ref:`current time zone <default-current-time-zone>` and returns
+aware datetime objects in ``cleaned_data``.
+
+If the current time zone raises an exception for datetimes that don't exist or
+are ambiguous because they fall in a DST transition (the timezones provided by
+pytz_ do this), such datetimes will be reported as invalid values.
+
+.. _time-zones-in-templates:
+
+Time zone aware output in templates
+===================================
+
+When you enable time zone support, Django converts aware datetime objects to
+the :ref:`current time zone <default-current-time-zone>` when they're rendered
+in templates. This behaves very much like :doc:`format localization
+</topics/i18n/formatting>`.
+
+.. warning::
+
+ Django doesn't convert naive datetime objects, because they could be
+ ambiguous, and because your code should never produce naive datetimes when
+ time zone support is enabled. However, you can force conversion with the
+ template filters described below.
+
+Conversion to local time isn't always appropriate -- you may be generating
+output for computers rather than for humans. The following filters and tags,
+provided the ``tz`` template library, allow you to control the time zone
+conversions.
+
+Template tags
+-------------
+
+.. templatetag:: localtime
+
+localtime
+~~~~~~~~~
+
+Enables or disables conversion of aware datetime objects to the current time
+zone in the contained block.
+
+This tag has exactly the same effects as the :setting:`USE_TZ` setting as far
+as the template engine is concerned. It allows a more fine grained control of
+conversion.
+
+To activate or deactivate conversion for a template block, use::
+
+ {% load tz %}
+
+ {% localtime on %}
+ {{ value }}
+ {% endlocaltime %}
+
+ {% localtime off %}
+ {{ value }}
+ {% endlocaltime %}
+
+.. note::
+
+ The value of :setting:`USE_TZ` isn't respected inside of a
+ ``{% localtime %}`` block.
+
+.. templatetag:: timezone
+
+timezone
+~~~~~~~~
+
+Sets or unsets the current time zone in the contained block. When the current
+time zone is unset, the default time zone applies.
+
+::
+
+ {% load tz %}
+
+ {% timezone "Europe/Paris" %}
+ Paris time: {{ value }}
+ {% endtimezone %}
+
+ {% timezone None %}
+ Server time: {{ value }}
+ {% endtimezone %}
+
+.. note::
+
+ In the second block, ``None`` resolves to the Python object ``None``
+ because isn't defined in the template context, not because it's the string
+ ``None``.
+
+.. templatetag:: get_current_timezone
+
+get_current_timezone
+~~~~~~~~~~~~~~~~~~~~
+
+When the :func:`django.core.context_processors.tz` context processor is
+enabled -- by default, it is -- each :class:`~django.template.RequestContext`
+contains a ``TIME_ZONE`` variable that provides the name of the current time
+zone.
+
+If you don't use a :class:`~django.template.RequestContext`, you can obtain
+this value with the ``get_current_timezone`` tag::
+
+ {% get_current_timezone as TIME_ZONE %}
+
+Template filters
+----------------
+
+These filters accept both aware and naive datetimes. For conversion purposes,
+they assume that naive datetimes are in the default time zone. They always
+return aware datetimes.
+
+.. templatefilter:: aslocaltime
+
+aslocaltime
+~~~~~~~~~~~
+
+Forces conversion of a single value to the current time zone.
+
+For example::
+
+ {% load tz %}
+
+ {{ value|aslocaltime }}
+
+.. templatefilter:: asutc
+
+asutc
+~~~~~
+
+Forces conversion of a single value to UTC.
+
+For example::
+
+ {% load tz %}
+
+ {{ value|asutc }}
+
+astimezone
+~~~~~~~~~~
+
+Forces conversion of a single value to an arbitrary timezone.
+
+The argument must be an instance of a :class:`~datetime.tzinfo` subclass or a
+time zone name. If it is a time zone name, pytz_ is required.
+
+For example::
+
+ {% load tz %}
+
+ {{ value|astimezone:"Europe/Paris" }}
+
+.. _time-zones-migration-guide:
+
+Migration guide
+===============
+
+Here's how to migrate a project that was started before Django supported time
+zones.
+
+Data
+----
+
+PostgreSQL
+~~~~~~~~~~
+
+The PostgreSQL backend stores datetimes as ``timestamp with time zone``. In
+practice, this means it converts datetimes from the connection's time zone to
+UTC on storage, and from UTC to the connection's time zone on retrieval.
+
+As a consequence, if you're using PostgreSQL, you can switch between ``USE_TZ
+= False`` and ``USE_TZ = True`` freely. The database connection's time zone
+will be set to :setting:`TIME_ZONE` or ``UTC`` respectively, so that Django
+obtains correct datetimes in all cases. You don't need to perform any data
+conversions.
+
+Other databases
+~~~~~~~~~~~~~~~
+
+Other backends store datetimes without time zone information. If you switch
+from ``USE_TZ = False`` to ``USE_TZ = True``, you must convert your data from
+local time to UTC -- which isn't deterministic if your local time has DST.
+
+Code
+----
+
+The first step is to add :setting:`USE_TZ = True <USE_TZ>` to your settings
+file and install pytz_ (if possible). At this point, things should mostly
+work. If you create naive datetime objects in your code, Django makes them
+aware when necessary.
+
+However, these conversions may fail around DST transitions, which means you
+aren't getting the full benefits of time zone support yet. Also, you're likely
+to run into a few problems because it's impossible to compare a naive datetime
+with an aware datetime. Since Django now gives you aware datetimes, you'll get
+exceptions wherever you compare a datetime that comes from a model or a form
+with a naive datetime that you've created in your code.
+
+So the second step is to refactor your code wherever you instanciate datetime
+objects to make them aware. This can be done incrementally.
+:mod:`django.utils.timezone` defines some handy helpers for compatibility
+code: :func:`~django.utils.timezone.is_aware`,
+:func:`~django.utils.timezone.is_naive`,
+:func:`~django.utils.timezone.make_aware`, and
+:func:`~django.utils.timezone.make_naive`.
+
+.. _pytz: http://pytz.sourceforge.net/
+.. _these issues: http://pytz.sourceforge.net/#problems-with-localtime
+.. _tz database: http://en.wikipedia.org/wiki/Tz_database