3

Django beginner here.

In official docs:

# Support for time zones is enabled in the default settings file, so
# Django expects a datetime with tzinfo for pub_date. Use timezone.now()
# instead of datetime.datetime.now() and it will do the right thing.
>>> from django.utils import timezone
>>> q = Question(question_text="What's new?", pub_date=timezone.now())

Trying do reproduce it in ./manage.py shell:

In [35]: from django.conf import settings

In [36]: settings.USE_TZ
Out[36]: True

In [37]: settings.TIME_ZONE
Out[37]: 'Europe/Moscow'

In [38]: from django.utils import timezone

    # UTC
In [39]: timezone.now()
Out[39]: datetime.datetime(2015, 10, 16, 9, 47, 50, 755418, tzinfo=<UTC>)

    # Actual time
In [40]: timezone.datetime.now()
Out[40]: datetime.datetime(2015, 10, 16, 12, 47, 54, 554197)

    # UTC
In [41]: timezone.activate("Europe/Moscow"); timezone.now()
Out[41]: datetime.datetime(2015, 10, 16, 9, 47, 59, 405269, tzinfo=<UTC>)

    # Actual time
In [42]: timezone.activate("Europe/Moscow"); timezone.datetime.now()
Out[42]: datetime.datetime(2015, 10, 16, 12, 48, 3, 179085)

When I'm running timezone.now() as specified in documentation, i'm getting UTC which is wrong. When i'm running timezone.datetime.now() (what i think is just call to datetime.datetime.now(), which is using system-wide timezone) i'm getting the right thing.

Tried with different timezones, still getting plain UTC.

What am I doing wrong?

mkurnikov
  • 1,251
  • 2
  • 15
  • 17

1 Answers1

2

timezone.now() behaves as it should: if USE_TZ=True; it returns the current time as an aware datetime object (in UTC).

2015-10-16 09:47:50+00:00 (UTC) is the same time moment as 2015-10-16 12:47:50+03:00 (MSK). The UTC time is rendered in the templates using your current time zone (defaults to TIME_ZONE setting and therefore it is unnecessary to set it explicitly using timezone.activate() here).

You can get the value explicitly using timezone.localtime(timezone.now()) (you don't need to).

jfs
  • 346,887
  • 152
  • 868
  • 1,518
  • It's weird, I thought settings.USE_TZ setting purpose is to convert automatically to TIME_ZONE. So, if I understand correctly, USE_TZ = True somehow provides means to "inject" timezone info to timezone.now() object. Am I right? – mkurnikov Oct 16 '15 at 10:27
  • 2
    @mkurnikov: it is not weird: [the best practice](http://stackoverflow.com/a/2532962/4279): use UTC everywhere, convert to local time for display: it is exactly what django does. To understand why should you prefer to deal with UTC if possible, consider for example, how would you [find if 24 hrs have passed between datetimes](http://stackoverflow.com/a/26313848/4279) – jfs Oct 16 '15 at 10:29
  • Ok, now i understand. Thank you for the answer. – mkurnikov Oct 16 '15 at 10:32