timezones.txt 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711
  1. .. _time-zones:
  2. ==========
  3. Time zones
  4. ==========
  5. .. _time-zones-overview:
  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.
  14. Even if your Web site is available in only one time zone, it's still good
  15. practice to store data in UTC in your database. One main reason is Daylight
  16. Saving Time (DST). Many countries have a system of DST, where clocks are moved
  17. forward in spring and backward in autumn. If you're working in local time,
  18. you're likely to encounter errors twice a year, when the transitions happen.
  19. (The pytz_ documentation discusses `these issues`_ in greater detail.) This
  20. probably doesn't matter for your blog, but it's a problem 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 use 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. It's as simple as:
  27. .. code-block:: bash
  28. $ sudo pip install pytz
  29. .. note::
  30. The default :file:`settings.py` file created by :djadmin:`django-admin.py
  31. startproject <startproject>` includes :setting:`USE_TZ = True <USE_TZ>`
  32. for convenience.
  33. .. note::
  34. There is also an independent but related :setting:`USE_L10N` setting that
  35. controls whether Django should activate format localization. See
  36. :doc:`/topics/i18n/formatting` for more details.
  37. If you're wrestling with a particular problem, start with the :ref:`time zone
  38. FAQ <time-zones-faq>`.
  39. Concepts
  40. ========
  41. .. _naive_vs_aware_datetimes:
  42. Naive and aware datetime objects
  43. --------------------------------
  44. Python's :class:`datetime.datetime` objects have a ``tzinfo`` attribute that
  45. can be used to store time zone information, represented as an instance of a
  46. subclass of :class:`datetime.tzinfo`. When this attribute is set and describes
  47. an offset, a datetime object is **aware**. Otherwise, it's **naive**.
  48. You can use :func:`~django.utils.timezone.is_aware` and
  49. :func:`~django.utils.timezone.is_naive` to determine whether datetimes are
  50. aware or naive.
  51. When time zone support is disabled, Django uses naive datetime objects in local
  52. time. This is simple and sufficient for many use cases. In this mode, to obtain
  53. the current time, you would write::
  54. import datetime
  55. now = datetime.datetime.now()
  56. When time zone support is enabled, Django uses time-zone-aware datetime
  57. objects. If your code creates datetime objects, they should be aware too. In
  58. this mode, the example above becomes::
  59. import datetime
  60. from django.utils.timezone import utc
  61. now = datetime.datetime.utcnow().replace(tzinfo=utc)
  62. .. note::
  63. :mod:`django.utils.timezone` provides a
  64. :func:`~django.utils.timezone.now()` function that returns a naive or
  65. aware datetime object according to the value of :setting:`USE_TZ`.
  66. .. warning::
  67. Dealing with aware datetime objects isn't always intuitive. For instance,
  68. the ``tzinfo`` argument of the standard datetime constructor doesn't work
  69. reliably for time zones with DST. Using UTC is generally safe; if you're
  70. using other time zones, you should review the `pytz`_ documentation
  71. carefully.
  72. .. note::
  73. Python's :class:`datetime.time` objects also feature a ``tzinfo``
  74. attribute, and PostgreSQL has a matching ``time with time zone`` type.
  75. However, as PostgreSQL's docs put it, this type "exhibits properties which
  76. lead to questionable usefulness".
  77. Django only supports naive time objects and will raise an exception if you
  78. attempt to save an aware time object.
  79. .. _naive-datetime-objects:
  80. Interpretation of naive datetime objects
  81. ----------------------------------------
  82. When :setting:`USE_TZ` is ``True``, Django still accepts naive datetime
  83. objects, in order to preserve backwards-compatibility. When the database layer
  84. receives one, it attempts to make it aware by interpreting it in the
  85. :ref:`default time zone <default-current-time-zone>` and raises a warning.
  86. Unfortunately, during DST transitions, some datetimes don't exist or are
  87. ambiguous. In such situations, pytz_ raises an exception. Other
  88. :class:`~datetime.tzinfo` implementations, such as the local time zone used as
  89. a fallback when pytz_ isn't installed, may raise an exception or return
  90. inaccurate results. That's why you should always create aware datetime objects
  91. when time zone support is enabled.
  92. In practice, this is rarely an issue. Django gives you aware datetime objects
  93. in the models and forms, and most often, new datetime objects are created from
  94. existing ones through :class:`~datetime.timedelta` arithmetic. The only
  95. datetime that's often created in application code is the current time, and
  96. :func:`timezone.now() <django.utils.timezone.now>` automatically does the
  97. right thing.
  98. .. _default-current-time-zone:
  99. Default time zone and current time zone
  100. ---------------------------------------
  101. The **default time zone** is the time zone defined by the :setting:`TIME_ZONE`
  102. setting.
  103. The **current time zone** is the time zone that's used for rendering.
  104. You should set the current time zone 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 Web sites that 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. import pytz
  137. from django.utils import timezone
  138. class TimezoneMiddleware(object):
  139. def process_request(self, request):
  140. tzname = request.session.get('django_timezone')
  141. if tzname:
  142. timezone.activate(pytz.timezone(tzname))
  143. else:
  144. timezone.deactivate()
  145. Create a view that can set the current timezone::
  146. from django.shortcuts import redirect, render
  147. def set_timezone(request):
  148. if request.method == 'POST':
  149. request.session['django_timezone'] = request.POST['timezone']
  150. return redirect('/')
  151. else:
  152. return render(request, 'template.html', {'timezones': pytz.common_timezones})
  153. Include a form in ``template.html`` that will ``POST`` to this view:
  154. .. code-block:: html+django
  155. {% load tz %}
  156. <form action="{% url 'set_timezone' %}" method="POST">
  157. {% csrf_token %}
  158. <label for="timezone">Time zone:</label>
  159. <select name="timezone">
  160. {% for tz in timezones %}
  161. <option value="{{ tz }}"{% if tz == TIME_ZONE %} selected="selected"{% endif %}>{{ tz }}</option>
  162. {% endfor %}
  163. </select>
  164. <input type="submit" value="Set" />
  165. </form>
  166. .. _time-zones-in-forms:
  167. Time zone aware input in forms
  168. ==============================
  169. When you enable time zone support, Django interprets datetimes entered in
  170. forms in the :ref:`current time zone <default-current-time-zone>` and returns
  171. aware datetime objects in ``cleaned_data``.
  172. If the current time zone raises an exception for datetimes that don't exist or
  173. are ambiguous because they fall in a DST transition (the timezones provided by
  174. pytz_ do this), such datetimes will be reported as invalid values.
  175. .. _time-zones-in-templates:
  176. Time zone aware output in templates
  177. ===================================
  178. When you enable time zone support, Django converts aware datetime objects to
  179. the :ref:`current time zone <default-current-time-zone>` when they're rendered
  180. in templates. This behaves very much like :doc:`format localization
  181. </topics/i18n/formatting>`.
  182. .. warning::
  183. Django doesn't convert naive datetime objects, because they could be
  184. ambiguous, and because your code should never produce naive datetimes when
  185. time zone support is enabled. However, you can force conversion with the
  186. template filters described below.
  187. Conversion to local time isn't always appropriate -- you may be generating
  188. output for computers rather than for humans. The following filters and tags,
  189. provided by the ``tz`` template tag library, allow you to control the time zone
  190. conversions.
  191. Template tags
  192. -------------
  193. .. templatetag:: localtime
  194. localtime
  195. ~~~~~~~~~
  196. Enables or disables conversion of aware datetime objects to the current time
  197. zone in the contained block.
  198. This tag has exactly the same effects as the :setting:`USE_TZ` setting as far
  199. as the template engine is concerned. It allows a more fine grained control of
  200. conversion.
  201. To activate or deactivate conversion for a template block, use::
  202. {% load tz %}
  203. {% localtime on %}
  204. {{ value }}
  205. {% endlocaltime %}
  206. {% localtime off %}
  207. {{ value }}
  208. {% endlocaltime %}
  209. .. note::
  210. The value of :setting:`USE_TZ` isn't respected inside of a
  211. ``{% localtime %}`` block.
  212. .. templatetag:: timezone
  213. timezone
  214. ~~~~~~~~
  215. Sets or unsets the current time zone in the contained block. When the current
  216. time zone is unset, the default time zone applies.
  217. ::
  218. {% load tz %}
  219. {% timezone "Europe/Paris" %}
  220. Paris time: {{ value }}
  221. {% endtimezone %}
  222. {% timezone None %}
  223. Server time: {{ value }}
  224. {% endtimezone %}
  225. .. templatetag:: get_current_timezone
  226. get_current_timezone
  227. ~~~~~~~~~~~~~~~~~~~~
  228. When the ``django.core.context_processors.tz`` context processor is
  229. enabled -- by default, it is -- each :class:`~django.template.RequestContext`
  230. contains a ``TIME_ZONE`` variable that provides the name of the current time
  231. zone.
  232. If you don't use a :class:`~django.template.RequestContext`, you can obtain
  233. this value with the ``get_current_timezone`` tag::
  234. {% get_current_timezone as TIME_ZONE %}
  235. Template filters
  236. ----------------
  237. These filters accept both aware and naive datetimes. For conversion purposes,
  238. they assume that naive datetimes are in the default time zone. They always
  239. return aware datetimes.
  240. .. templatefilter:: localtime
  241. localtime
  242. ~~~~~~~~~
  243. Forces conversion of a single value to the current time zone.
  244. For example::
  245. {% load tz %}
  246. {{ value|localtime }}
  247. .. templatefilter:: utc
  248. utc
  249. ~~~
  250. Forces conversion of a single value to UTC.
  251. For example::
  252. {% load tz %}
  253. {{ value|utc }}
  254. .. templatefilter:: timezone
  255. timezone
  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|timezone:"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. Database
  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 instantiate 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.now`,
  301. :func:`~django.utils.timezone.is_aware`,
  302. :func:`~django.utils.timezone.is_naive`,
  303. :func:`~django.utils.timezone.make_aware`, and
  304. :func:`~django.utils.timezone.make_naive`.
  305. Finally, in order to help you locate code that needs upgrading, Django raises
  306. a warning when you attempt to save a naive datetime to the database::
  307. RuntimeWarning: DateTimeField ModelName.field_name received a naive
  308. datetime (2012-01-01 00:00:00) while time zone support is active.
  309. During development, you can turn such warnings into exceptions and get a
  310. traceback by adding the following to your settings file::
  311. import warnings
  312. warnings.filterwarnings(
  313. 'error', r"DateTimeField .* received a naive datetime",
  314. RuntimeWarning, r'django\.db\.models\.fields')
  315. Fixtures
  316. --------
  317. When serializing an aware datetime, the UTC offset is included, like this::
  318. "2011-09-01T13:20:30+03:00"
  319. For a naive datetime, it obviously isn't::
  320. "2011-09-01T13:20:30"
  321. For models with :class:`~django.db.models.DateTimeField`\ s, this difference
  322. makes it impossible to write a fixture that works both with and without time
  323. zone support.
  324. Fixtures generated with ``USE_TZ = False``, or before Django 1.4, use the
  325. "naive" format. If your project contains such fixtures, after you enable time
  326. zone support, you'll see :exc:`RuntimeWarning`\ s when you load them. To get
  327. rid of the warnings, you must convert your fixtures to the "aware" format.
  328. You can regenerate fixtures with :djadmin:`loaddata` then :djadmin:`dumpdata`.
  329. Or, if they're small enough, you can simply edit them to add the UTC offset
  330. that matches your :setting:`TIME_ZONE` to each serialized datetime.
  331. .. _time-zones-faq:
  332. FAQ
  333. ===
  334. Setup
  335. -----
  336. 1. **I don't need multiple time zones. Should I enable time zone support?**
  337. Yes. When time zone support is enabled, Django uses a more accurate model
  338. of local time. This shields you from subtle and unreproducible bugs around
  339. Daylight Saving Time (DST) transitions.
  340. In this regard, time zones are comparable to ``unicode`` in Python. At first
  341. it's hard. You get encoding and decoding errors. Then you learn the rules.
  342. And some problems disappear -- you never get mangled output again when your
  343. application receives non-ASCII input.
  344. When you enable time zone support, you'll encounter some errors because
  345. you're using naive datetimes where Django expects aware datetimes. Such
  346. errors show up when running tests and they're easy to fix. You'll quickly
  347. learn how to avoid invalid operations.
  348. On the other hand, bugs caused by the lack of time zone support are much
  349. harder to prevent, diagnose and fix. Anything that involves scheduled tasks
  350. or datetime arithmetic is a candidate for subtle bugs that will bite you
  351. only once or twice a year.
  352. For these reasons, time zone support is enabled by default in new projects,
  353. and you should keep it unless you have a very good reason not to.
  354. 2. **I've enabled time zone support. Am I safe?**
  355. Maybe. You're better protected from DST-related bugs, but you can still
  356. shoot yourself in the foot by carelessly turning naive datetimes into aware
  357. datetimes, and vice-versa.
  358. If your application connects to other systems -- for instance, if it queries
  359. a Web service -- make sure datetimes are properly specified. To transmit
  360. datetimes safely, their representation should include the UTC offset, or
  361. their values should be in UTC (or both!).
  362. Finally, our calendar system contains interesting traps for computers::
  363. >>> import datetime
  364. >>> def one_year_before(value): # DON'T DO THAT!
  365. ... return value.replace(year=value.year - 1)
  366. >>> one_year_before(datetime.datetime(2012, 3, 1, 10, 0))
  367. datetime.datetime(2011, 3, 1, 10, 0)
  368. >>> one_year_before(datetime.datetime(2012, 2, 29, 10, 0))
  369. Traceback (most recent call last):
  370. ...
  371. ValueError: day is out of range for month
  372. (To implement this function, you must decide whether 2012-02-29 minus
  373. one year is 2011-02-28 or 2011-03-01, which depends on your business
  374. requirements.)
  375. 3. **Should I install pytz?**
  376. Yes. Django has a policy of not requiring external dependencies, and for
  377. this reason pytz_ is optional. However, it's much safer to install it.
  378. As soon as you activate time zone support, Django needs a definition of the
  379. default time zone. When pytz is available, Django loads this definition
  380. from the `tz database`_. This is the most accurate solution. Otherwise, it
  381. relies on the difference between local time and UTC, as reported by the
  382. operating system, to compute conversions. This is less reliable, especially
  383. around DST transitions.
  384. Furthermore, if you want to support users in more than one time zone, pytz
  385. is the reference for time zone definitions.
  386. Troubleshooting
  387. ---------------
  388. 1. **My application crashes with** ``TypeError: can't compare offset-naive``
  389. ``and offset-aware datetimes`` **-- what's wrong?**
  390. Let's reproduce this error by comparing a naive and an aware datetime::
  391. >>> import datetime
  392. >>> from django.utils import timezone
  393. >>> naive = datetime.datetime.utcnow()
  394. >>> aware = naive.replace(tzinfo=timezone.utc)
  395. >>> naive == aware
  396. Traceback (most recent call last):
  397. ...
  398. TypeError: can't compare offset-naive and offset-aware datetimes
  399. If you encounter this error, most likely your code is comparing these two
  400. things:
  401. - a datetime provided by Django -- for instance, a value read from a form or
  402. a model field. Since you enabled time zone support, it's aware.
  403. - a datetime generated by your code, which is naive (or you wouldn't be
  404. reading this).
  405. Generally, the correct solution is to change your code to use an aware
  406. datetime instead.
  407. If you're writing a pluggable application that's expected to work
  408. independently of the value of :setting:`USE_TZ`, you may find
  409. :func:`django.utils.timezone.now` useful. This function returns the current
  410. date and time as a naive datetime when ``USE_TZ = False`` and as an aware
  411. datetime when ``USE_TZ = True``. You can add or subtract
  412. :class:`datetime.timedelta` as needed.
  413. 2. **I see lots of** ``RuntimeWarning: DateTimeField received a naive
  414. datetime`` ``(YYYY-MM-DD HH:MM:SS)`` ``while time zone support is active``
  415. **-- is that bad?**
  416. When time zone support is enabled, the database layer expects to receive
  417. only aware datetimes from your code. This warning occurs when it receives a
  418. naive datetime. This indicates that you haven't finished porting your code
  419. for time zone support. Please refer to the :ref:`migration guide
  420. <time-zones-migration-guide>` for tips on this process.
  421. In the meantime, for backwards compatibility, the datetime is considered to
  422. be in the default time zone, which is generally what you expect.
  423. 3. ``now.date()`` **is yesterday! (or tomorrow)**
  424. If you've always used naive datetimes, you probably believe that you can
  425. convert a datetime to a date by calling its :meth:`~datetime.datetime.date`
  426. method. You also consider that a :class:`~datetime.date` is a lot like a
  427. :class:`~datetime.datetime`, except that it's less accurate.
  428. None of this is true in a time zone aware environment::
  429. >>> import datetime
  430. >>> import pytz
  431. >>> paris_tz = pytz.timezone("Europe/Paris")
  432. >>> new_york_tz = pytz.timezone("America/New_York")
  433. >>> paris = paris_tz.localize(datetime.datetime(2012, 3, 3, 1, 30))
  434. # This is the correct way to convert between time zones with pytz.
  435. >>> new_york = new_york_tz.normalize(paris.astimezone(new_york_tz))
  436. >>> paris == new_york, paris.date() == new_york.date()
  437. (True, False)
  438. >>> paris - new_york, paris.date() - new_york.date()
  439. (datetime.timedelta(0), datetime.timedelta(1))
  440. >>> paris
  441. datetime.datetime(2012, 3, 3, 1, 30, tzinfo=<DstTzInfo 'Europe/Paris' CET+1:00:00 STD>)
  442. >>> new_york
  443. datetime.datetime(2012, 3, 2, 19, 30, tzinfo=<DstTzInfo 'America/New_York' EST-1 day, 19:00:00 STD>)
  444. As this example shows, the same datetime has a different date, depending on
  445. the time zone in which it is represented. But the real problem is more
  446. fundamental.
  447. A datetime represents a **point in time**. It's absolute: it doesn't depend
  448. on anything. On the contrary, a date is a **calendaring concept**. It's a
  449. period of time whose bounds depend on the time zone in which the date is
  450. considered. As you can see, these two concepts are fundamentally different,
  451. and converting a datetime to a date isn't a deterministic operation.
  452. What does this mean in practice?
  453. Generally, you should avoid converting a :class:`~datetime.datetime` to
  454. :class:`~datetime.date`. For instance, you can use the :tfilter:`date`
  455. template filter to only show the date part of a datetime. This filter will
  456. convert the datetime into the current time zone before formatting it,
  457. ensuring the results appear correctly.
  458. If you really need to do the conversion yourself, you must ensure the
  459. datetime is converted to the appropriate time zone first. Usually, this
  460. will be the current timezone::
  461. >>> from django.utils import timezone
  462. >>> timezone.activate(pytz.timezone("Asia/Singapore"))
  463. # For this example, we just set the time zone to Singapore, but here's how
  464. # you would obtain the current time zone in the general case.
  465. >>> current_tz = timezone.get_current_timezone()
  466. # Again, this is the correct way to convert between time zones with pytz.
  467. >>> local = current_tz.normalize(paris.astimezone(current_tz))
  468. >>> local
  469. datetime.datetime(2012, 3, 3, 8, 30, tzinfo=<DstTzInfo 'Asia/Singapore' SGT+8:00:00 STD>)
  470. >>> local.date()
  471. datetime.date(2012, 3, 3)
  472. 4. **I get an error** "``Are time zone definitions for your database and pytz
  473. installed?``" **pytz is installed, so I guess the problem is my database?**
  474. If you are using MySQL, see the :ref:`mysql-time-zone-definitions` section
  475. of the MySQL notes for instructions on loading time zone definitions.
  476. Usage
  477. -----
  478. 1. **I have a string** ``"2012-02-21 10:28:45"`` **and I know it's in the**
  479. ``"Europe/Helsinki"`` **time zone. How do I turn that into an aware
  480. datetime?**
  481. This is exactly what pytz_ is for.
  482. >>> from django.utils.dateparse import parse_datetime
  483. >>> naive = parse_datetime("2012-02-21 10:28:45")
  484. >>> import pytz
  485. >>> pytz.timezone("Europe/Helsinki").localize(naive, is_dst=None)
  486. datetime.datetime(2012, 2, 21, 10, 28, 45, tzinfo=<DstTzInfo 'Europe/Helsinki' EET+2:00:00 STD>)
  487. Note that ``localize`` is a pytz extension to the :class:`~datetime.tzinfo`
  488. API. Also, you may want to catch ``pytz.InvalidTimeError``. The
  489. documentation of pytz contains `more examples`_. You should review it
  490. before attempting to manipulate aware datetimes.
  491. 2. **How can I obtain the local time in the current time zone?**
  492. Well, the first question is, do you really need to?
  493. You should only use local time when you're interacting with humans, and the
  494. template layer provides :ref:`filters and tags <time-zones-in-templates>`
  495. to convert datetimes to the time zone of your choice.
  496. Furthermore, Python knows how to compare aware datetimes, taking into
  497. account UTC offsets when necessary. It's much easier (and possibly faster)
  498. to write all your model and view code in UTC. So, in most circumstances,
  499. the datetime in UTC returned by :func:`django.utils.timezone.now` will be
  500. sufficient.
  501. For the sake of completeness, though, if you really want the local time
  502. in the current time zone, here's how you can obtain it::
  503. >>> from django.utils import timezone
  504. >>> timezone.localtime(timezone.now())
  505. datetime.datetime(2012, 3, 3, 20, 10, 53, 873365, tzinfo=<DstTzInfo 'Europe/Paris' CET+1:00:00 STD>)
  506. In this example, pytz_ is installed and the current time zone is
  507. ``"Europe/Paris"``.
  508. 3. **How can I see all available time zones?**
  509. pytz_ provides helpers_, including a list of current time zones and a list
  510. of all available time zones -- some of which are only of historical
  511. interest.
  512. .. _pytz: http://pytz.sourceforge.net/
  513. .. _more examples: http://pytz.sourceforge.net/#example-usage
  514. .. _these issues: http://pytz.sourceforge.net/#problems-with-localtime
  515. .. _helpers: http://pytz.sourceforge.net/#helpers
  516. .. _tz database: http://en.wikipedia.org/wiki/Tz_database