django's timezone.now does not show the right time

DjangoDjango Timezone

Django Problem Overview


My server is located in London.

In my settings.py I have:

TIME_ZONE = 'Europe/Moscow'
USE_TZ = True

But when I execute this:

from django.utils import timezone

print timezone.now().hour

the code prints London's time. What am I doing wrong?

UPDATE:

>> timezone.now()
datetime.datetime(2013, 4, 16, 12, 28, 52, 797923, tzinfo=<UTC>)

Interesting... tzinfo = <UTC>. So maybe it prints not a London time, but UTC's +0 time? Anyway, is there any way to make Django show Moscow time?

Also when I render template with now = timezone.now()

{{ now.hour }} prints 12 (London time)

{{ now|date:"G" }} prints 16 (Moscow time)

Django Solutions


Solution 1 - Django

See question #2 in the "Usage" section of the Django docs.

>>> from django.utils import timezone
>>> timezone.localtime(timezone.now())

Since the doc above also talks about a best practice, including an excerpt below:

> How can I obtain the local time in the current time zone? > > Well, the first question is, do you really need to? > > You should only use local time when you’re interacting with humans, > and the template layer provides filters and tags to convert datetimes > to the time zone of your choice. > > Furthermore, Python knows how to compare aware datetimes, taking into > account UTC offsets when necessary. It’s much easier (and possibly > faster) to write all your model and view code in UTC. So, in most > circumstances, the datetime in UTC returned by > django.utils.timezone.now() will be sufficient.

Solution 2 - Django

from django.utils import timezone
time = timezone.localtime() 

It will give your local time that whatever your TIME_ZONE set to.

time = timezone.localtime(timezone.now()) # same result, but it is redundant.

Solution 3 - Django

The reason it works in the template but not in the view python code is somewhat in the docs: https://docs.djangoproject.com/en/3.1/ref/settings/#std:setting-TIME_ZONE

"..... this is the default time zone that Django will use to display datetimes in templates and to interpret datetimes entered in forms."

This is why {{ now|date:"G" }} prints 16 (Moscow time) prints the Moscow time!

Another note is timezone.now() in a normally configured Django app will pick up whatever TIME_ZONE is set to in the settings ('America/New_York' in example below). But can be overridden as well (see below to Paris for example in a middleware or directly in a view for that request)

In [27]: timezone.localtime(timezone.now())

Out[27]: datetime.datetime(2021, 2, 23, 1, 53, 49, 793743, tzinfo=<DstTzInfo 'America/New_York' EST-1 day, 19:00:00 STD>)

In [29]: timezone.activate(pytz.timezone("Europe/Paris"))

In [30]: timezone.localtime(timezone.now())

Out[30]: datetime.datetime(2021, 2, 23, 7, 54, 19, 21898, tzinfo=<DstTzInfo 'Europe/Paris' CET+1:00:00 STD>)

Solution 4 - Django

django's use_tz = True returns datetime object in timezone. if set to false, it uses system default (locale) time which is naïve. I performed a small experiment to clarify this confusion

test1: when use_tz = true; timezone= us/eastern; system timezone: UTC+5:30

datetime.datetime.today() # returned naive datetime with locale time
timezone.now() returned # UTC
timezone.localtime() # returned us/eastern 

test2: when use_tz = true; timezone= us/eastern; system timezone: UTC-5

datetime.datetime.today() # returned naive datetime in with locale time
timezone.now() # returned UTC timezone
timezone.localtime() # in US/eastern timezone

test3: when use_tz = False; timezone= us/eastern; system timezone: UTC-5

timezone.now() # returned naive datetime with system time
timezone.localtime() # returned traceback ValueError: localtime() cannot be applied to a naive datetime

test4: when use_tz = False; timezone= UTC; system timezone: UTC+5:30

datetime.datetime.today() # returned naive datetime in system timezone
timezone.now() # returned naive datetime in system timezone
timezone.localtime() # returned traceback

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionimkostView Question on Stackoverflow
Solution 1 - DjangoDaniel HepperView Answer on Stackoverflow
Solution 2 - DjangoMason LiuView Answer on Stackoverflow
Solution 3 - DjangochachraView Answer on Stackoverflow
Solution 4 - DjangoAman BagrechaView Answer on Stackoverflow