timezones.txt 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429
  1. .. _time-zones:
  2. ==========
  3. Time zones
  4. ==========
  5. .. versionadded:: 1.4
  6. Overview
  7. ========
  8. When support for time zones is enabled, Django stores date and time
  9. information in UTC in the database, uses time zone-aware datetime objects
  10. internally, and translates them to the end user's time zone in templates and
  11. forms.
  12. This is handy if your users live in more than one time zone and you want to
  13. display date and time information according to each user's wall clock. Even if
  14. your website is available in only one time zone, it's still a good practice to
  15. store data in UTC in your database. Here is why.
  16. Many countries have a system of daylight saving time (DST), where clocks are
  17. moved forwards in spring and backwards in autumn. If you're working in local
  18. time, you're likely to encounter errors twice a year, when the transitions
  19. happen. pytz' docs discuss `these issues`_ in greater detail. It probably
  20. doesn't matter for your blog, but it's more annoying if you over-bill or
  21. under-bill your customers by one hour, twice a year, every year. The solution
  22. to this problem is to use UTC in the code and local time only when
  23. interacting with end users.
  24. Time zone support is disabled by default. To enable it, set :setting:`USE_TZ =
  25. True <USE_TZ>` in your settings file. Installing pytz_ is highly recommended,
  26. but not mandatory.
  27. .. note::
  28. The default :file:`settings.py` file created by :djadmin:`django-admin.py
  29. startproject <startproject>` includes :setting:`USE_TZ = True <USE_TZ>`
  30. for convenience.
  31. .. note::
  32. There is also an independent but related :setting:`USE_L10N` setting that
  33. controls if Django should activate format localization. See
  34. :doc:`/topics/i18n/formatting` for more details.
  35. Concepts
  36. ========
  37. Naive and aware datetime objects
  38. --------------------------------
  39. Python's :class:`datetime.datetime` objects have a ``tzinfo`` attribute that
  40. can be used to store time zone information, represented as an instance of a
  41. subclass of :class:`datetime.tzinfo`. When this attribute is set and describes
  42. an offset, a datetime object is **aware**; otherwise, it's **naive**.
  43. You can use :func:`~django.utils.timezone.is_aware` and
  44. :func:`~django.utils.timezone.is_naive` to determine if datetimes are aware or
  45. naive.
  46. When time zone support is disabled, Django uses naive datetime objects in local
  47. time. This is simple and sufficient for many use cases. In this mode, to obtain
  48. the current time, you would write::
  49. import datetime
  50. now = datetime.datetime.now()
  51. When time zone support is enabled, Django uses time zone aware datetime
  52. objects. If your code creates datetime objects, they should be aware too. In
  53. this mode, the example above becomes::
  54. import datetime
  55. from django.utils.timezone import utc
  56. now = datetime.datetime.utcnow().replace(tzinfo=utc)
  57. .. note::
  58. :mod:`django.utils.timezone` provides a
  59. :func:`~django.utils.timezone.now()` function that returns a naive or
  60. aware datetime object according to the value of :setting:`USE_TZ`.
  61. .. warning::
  62. Dealing with aware datetime objects isn't always intuitive. For instance,
  63. the ``tzinfo`` argument of the standard datetime constructor doesn't work
  64. reliably for time zones with DST. Using UTC is generally safe; if you're
  65. using other time zones, you should review `pytz' documentation <pytz>`_
  66. carefully.
  67. .. note::
  68. Python's :class:`datetime.time` objects also feature a ``tzinfo``
  69. attribute, and PostgreSQL has a matching ``time with time zone`` type.
  70. However, as PostgreSQL's docs put it, this type "exhibits properties which
  71. lead to questionable usefulness".
  72. Django only supports naive time objects and will raise an exception if you
  73. attempt to save an aware time object.
  74. .. _naive-datetime-objects:
  75. Interpretation of naive datetime objects
  76. ----------------------------------------
  77. When :setting:`USE_TZ` is ``True``, Django still accepts naive datetime
  78. objects, in order to preserve backwards-compatibility. It attempts to make them
  79. aware by interpreting them in the :ref:`default time zone
  80. <default-current-time-zone>`.
  81. Unfortunately, during DST transitions, some datetimes don't exist or are
  82. ambiguous. In such situations, pytz_ raises an exception. Other
  83. :class:`~datetime.tzinfo` implementations, such as the local time zone used as
  84. a fallback when pytz_ isn't installed, may raise an exception or return
  85. inaccurate results. That's why you should always create aware datetime objects
  86. when time zone support is enabled.
  87. In practice, this is rarely an issue. Django gives you aware datetime objects
  88. in the models and forms, and most often, new datetime objects are created from
  89. existing ones through :class:`~datetime.timedelta` arithmetic. The only
  90. datetime that's often created in application code is the current time, and
  91. :func:`timezone.now() <django.utils.timezone.now>` automatically does the
  92. right thing.
  93. .. _default-current-time-zone:
  94. Default time zone and current time zone
  95. ---------------------------------------
  96. The **default time zone** is the time zone defined by the :setting:`TIME_ZONE`
  97. setting.
  98. When pytz_ is available, Django loads the definition of the default time zone
  99. from the `tz database`_. This is the most accurate solution. Otherwise, it
  100. relies on the difference between local time and UTC, as reported by the
  101. operating system, to compute conversions. This is less reliable, especially
  102. around DST transitions.
  103. The **current time zone** is the time zone that's used for rendering.
  104. You should set it to the end user's actual time zone with
  105. :func:`~django.utils.timezone.activate`. Otherwise, the default time zone is
  106. used.
  107. .. note::
  108. As explained in the documentation of :setting:`TIME_ZONE`, Django sets
  109. environment variables so that its process runs in the default time zone.
  110. This happens regardless of the value of :setting:`USE_TZ` and of the
  111. current time zone.
  112. When :setting:`USE_TZ` is ``True``, this is useful to preserve
  113. backwards-compatibility with applications that still rely on local time.
  114. However, :ref:`as explained above <naive-datetime-objects>`, this isn't
  115. entirely reliable, and you should always work with aware datetimes in UTC
  116. in your own code. For instance, use
  117. :meth:`~datetime.datetime.utcfromtimestamp` instead of
  118. :meth:`~datetime.datetime.fromtimestamp` -- and don't forget to set
  119. ``tzinfo`` to :data:`~django.utils.timezone.utc`.
  120. Selecting the current time zone
  121. -------------------------------
  122. The current time zone is the equivalent of the current :term:`locale <locale
  123. name>` for translations. However, there's no equivalent of the
  124. ``Accept-Language`` HTTP header that Django could use to determine the user's
  125. time zone automatically. Instead, Django provides :ref:`time zone selection
  126. functions <time-zone-selection-functions>`. Use them to build the time zone
  127. selection logic that makes sense for you.
  128. Most websites who care about time zones just ask users in which time zone they
  129. live and store this information in the user's profile. For anonymous users,
  130. they use the time zone of their primary audience or UTC. pytz_ provides
  131. helpers, like a list of time zones per country, that you can use to pre-select
  132. the most likely choices.
  133. Here's an example that stores the current timezone in the session. (It skips
  134. error handling entirely for the sake of simplicity.)
  135. Add the following middleware to :setting:`MIDDLEWARE_CLASSES`::
  136. from django.utils import timezone
  137. class TimezoneMiddleware(object):
  138. def process_request(self, request):
  139. tz = request.session.get('django_timezone')
  140. if tz:
  141. timezone.activate(tz)
  142. Create a view that can set the current timezone::
  143. import pytz
  144. from django.shortcuts import redirect, render
  145. def set_timezone(request):
  146. if request.method == 'POST':
  147. request.session[session_key] = pytz.timezone(request.POST['timezone'])
  148. return redirect('/')
  149. else:
  150. return render(request, 'template.html', {'timezones': pytz.common_timezones})
  151. Include in :file:`template.html` a form that will ``POST`` to this view:
  152. .. code-block:: html+django
  153. {% load tz %}{% load url from future %}
  154. <form action="{% url 'set_timezone' %}" method="POST">
  155. {% csrf_token %}
  156. <label for="timezone">Time zone:</label>
  157. <select name="timezone">
  158. {% for tz in timezones %}
  159. <option value="{{ tz }}"{% if tz == TIME_ZONE %} selected="selected"{% endif %}>{{ tz }}</option>
  160. {% endfor %}
  161. </select>
  162. <input type="submit" value="Set" />
  163. </form>
  164. Time zone aware input in forms
  165. ==============================
  166. When you enable time zone support, Django interprets datetimes entered in
  167. forms in the :ref:`current time zone <default-current-time-zone>` and returns
  168. aware datetime objects in ``cleaned_data``.
  169. If the current time zone raises an exception for datetimes that don't exist or
  170. are ambiguous because they fall in a DST transition (the timezones provided by
  171. pytz_ do this), such datetimes will be reported as invalid values.
  172. .. _time-zones-in-templates:
  173. Time zone aware output in templates
  174. ===================================
  175. When you enable time zone support, Django converts aware datetime objects to
  176. the :ref:`current time zone <default-current-time-zone>` when they're rendered
  177. in templates. This behaves very much like :doc:`format localization
  178. </topics/i18n/formatting>`.
  179. .. warning::
  180. Django doesn't convert naive datetime objects, because they could be
  181. ambiguous, and because your code should never produce naive datetimes when
  182. time zone support is enabled. However, you can force conversion with the
  183. template filters described below.
  184. Conversion to local time isn't always appropriate -- you may be generating
  185. output for computers rather than for humans. The following filters and tags,
  186. provided the ``tz`` template library, allow you to control the time zone
  187. conversions.
  188. Template tags
  189. -------------
  190. .. templatetag:: localtime
  191. localtime
  192. ~~~~~~~~~
  193. Enables or disables conversion of aware datetime objects to the current time
  194. zone in the contained block.
  195. This tag has exactly the same effects as the :setting:`USE_TZ` setting as far
  196. as the template engine is concerned. It allows a more fine grained control of
  197. conversion.
  198. To activate or deactivate conversion for a template block, use::
  199. {% load tz %}
  200. {% localtime on %}
  201. {{ value }}
  202. {% endlocaltime %}
  203. {% localtime off %}
  204. {{ value }}
  205. {% endlocaltime %}
  206. .. note::
  207. The value of :setting:`USE_TZ` isn't respected inside of a
  208. ``{% localtime %}`` block.
  209. .. templatetag:: timezone
  210. timezone
  211. ~~~~~~~~
  212. Sets or unsets the current time zone in the contained block. When the current
  213. time zone is unset, the default time zone applies.
  214. ::
  215. {% load tz %}
  216. {% timezone "Europe/Paris" %}
  217. Paris time: {{ value }}
  218. {% endtimezone %}
  219. {% timezone None %}
  220. Server time: {{ value }}
  221. {% endtimezone %}
  222. .. note::
  223. In the second block, ``None`` resolves to the Python object ``None``
  224. because isn't defined in the template context, not because it's the string
  225. ``None``.
  226. .. templatetag:: get_current_timezone
  227. get_current_timezone
  228. ~~~~~~~~~~~~~~~~~~~~
  229. When the :func:`django.core.context_processors.tz` context processor is
  230. enabled -- by default, it is -- each :class:`~django.template.RequestContext`
  231. contains a ``TIME_ZONE`` variable that provides the name of the current time
  232. zone.
  233. If you don't use a :class:`~django.template.RequestContext`, you can obtain
  234. this value with the ``get_current_timezone`` tag::
  235. {% get_current_timezone as TIME_ZONE %}
  236. Template filters
  237. ----------------
  238. These filters accept both aware and naive datetimes. For conversion purposes,
  239. they assume that naive datetimes are in the default time zone. They always
  240. return aware datetimes.
  241. .. templatefilter:: aslocaltime
  242. aslocaltime
  243. ~~~~~~~~~~~
  244. Forces conversion of a single value to the current time zone.
  245. For example::
  246. {% load tz %}
  247. {{ value|aslocaltime }}
  248. .. templatefilter:: asutc
  249. asutc
  250. ~~~~~
  251. Forces conversion of a single value to UTC.
  252. For example::
  253. {% load tz %}
  254. {{ value|asutc }}
  255. astimezone
  256. ~~~~~~~~~~
  257. Forces conversion of a single value to an arbitrary timezone.
  258. The argument must be an instance of a :class:`~datetime.tzinfo` subclass or a
  259. time zone name. If it is a time zone name, pytz_ is required.
  260. For example::
  261. {% load tz %}
  262. {{ value|astimezone:"Europe/Paris" }}
  263. .. _time-zones-migration-guide:
  264. Migration guide
  265. ===============
  266. Here's how to migrate a project that was started before Django supported time
  267. zones.
  268. Data
  269. ----
  270. PostgreSQL
  271. ~~~~~~~~~~
  272. The PostgreSQL backend stores datetimes as ``timestamp with time zone``. In
  273. practice, this means it converts datetimes from the connection's time zone to
  274. UTC on storage, and from UTC to the connection's time zone on retrieval.
  275. As a consequence, if you're using PostgreSQL, you can switch between ``USE_TZ
  276. = False`` and ``USE_TZ = True`` freely. The database connection's time zone
  277. will be set to :setting:`TIME_ZONE` or ``UTC`` respectively, so that Django
  278. obtains correct datetimes in all cases. You don't need to perform any data
  279. conversions.
  280. Other databases
  281. ~~~~~~~~~~~~~~~
  282. Other backends store datetimes without time zone information. If you switch
  283. from ``USE_TZ = False`` to ``USE_TZ = True``, you must convert your data from
  284. local time to UTC -- which isn't deterministic if your local time has DST.
  285. Code
  286. ----
  287. The first step is to add :setting:`USE_TZ = True <USE_TZ>` to your settings
  288. file and install pytz_ (if possible). At this point, things should mostly
  289. work. If you create naive datetime objects in your code, Django makes them
  290. aware when necessary.
  291. However, these conversions may fail around DST transitions, which means you
  292. aren't getting the full benefits of time zone support yet. Also, you're likely
  293. to run into a few problems because it's impossible to compare a naive datetime
  294. with an aware datetime. Since Django now gives you aware datetimes, you'll get
  295. exceptions wherever you compare a datetime that comes from a model or a form
  296. with a naive datetime that you've created in your code.
  297. So the second step is to refactor your code wherever you instanciate datetime
  298. objects to make them aware. This can be done incrementally.
  299. :mod:`django.utils.timezone` defines some handy helpers for compatibility
  300. code: :func:`~django.utils.timezone.is_aware`,
  301. :func:`~django.utils.timezone.is_naive`,
  302. :func:`~django.utils.timezone.make_aware`, and
  303. :func:`~django.utils.timezone.make_naive`.
  304. .. _pytz: http://pytz.sourceforge.net/
  305. .. _these issues: http://pytz.sourceforge.net/#problems-with-localtime
  306. .. _tz database: http://en.wikipedia.org/wiki/Tz_database