4

I have setup my django and i have a model with an auto_now=True, because my SQL server timezone has been set to 'Asia/Shanghai', so i would like to set django to this timezone too. i have set it up TIME_ZONE='Asia/Shanghai' and Use_TZ=True.

I checked that datetime.datetime.now() can give me the right timezone time. but the django.utils.timezone.now() time is still UTC time as shown in below shell output.

I think this explain why my auton_now object timezone is always in UTC. I am planning to set in models.py the default to use my datetime.datetime.now() object, but i have a warning about this.

How can i set up settings.py such that the django.utils.timezone object can be set correctly too?

>>> timezone.get_current_timezone()
<DstTzInfo 'Asia/Shanghai' LMT+8:06:00 STD>
>>> timezone.now()
datetime.datetime(2018, 1, 18, 10, 11, 0, 936572, tzinfo=<UTC>)
>>>
>>> datetime.datetime.now()
datetime.datetime(2018, 1, 18, 18, 20, 23, 722825)
Louis Lau
  • 41
  • 1
  • 2

2 Answers2

5

This is because django saves its dates as UTC by default, it does this since UTC is easiest to manipulate into different timezones. If you want to reference your timezone while using timezone.now() have a look at the documentation.

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.

For the sake of completeness, though, if you really want the local time in the current time zone, here’s how you can obtain it:

>>> from django.utils import timezone
>>> timezone.localtime(timezone.now())
datetime.datetime(2012, 3, 3, 20, 10, 53, 873365, tzinfo=<DstTzInfo 'Europe/Paris' CET+1:00:00 STD>)

I would recommend sticking to UTC, and converting your time on the go.
For more information on how to do so, read this https://docs.djangoproject.com/en/1.11/topics/i18n/timezones/

Just to add on the reason behind Django stating a warning when using datetime.datetime.now() is because of it being a naive time (not timezone aware/missing tzinfo attr). E. g.

datetime: Naive time (not aware of timezone).

>>>datetime.datetime.now()
datetime.datetime(2018, 1, 18, 21, 31, 16, 349259)

django.utils.timezone: Aware of UTC timezone.

>>>timezone.now()
datetime.datetime(2018, 1, 18, 13, 31, 16, 349259, tzinfo=<UTC>)

django.utils.timezone: Aware of local timezone

>>>timezone.localtime(timezone.now())
datetime.datetime(2018, 1, 18, 21, 31, 16, 349259, tzinfo=<DstTzInfo 'Asia/Shanghai' CST+8:00:00 STD>)

Since django sets up auto_now with these settings

As currently implemented, setting auto_now or auto_now_add to True will cause the field to have editable=False and blank=True set.

If you intend on imitating django's DateTimeField behavior I would recommend setting your field up like this.

from django.utils import timezone

pub_date = models.DateTimeField(
    default=timezone.localtime(timezone.now()),
    editable=False,
    blank=True,
    )

Other interesting material on handling dates and time. http://pytz.sourceforge.net https://docs.python.org/3/library/datetime.html

Community
  • 1
  • 1
0

You can try this:

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

https://stackoverflow.com/a/16037255/15553557

Nat Riddle
  • 928
  • 1
  • 10
  • 24
Dany Leon
  • 1
  • 1