In settings.py
I have:
TIME_ZONE = 'Asia/Singapore'
USE_I18N = True
USE_L10N = True
USE_TZ = True
If a user (who is living in Singapore) enters 2013-10-07 01:00 A.M.
in a form on my site, the value stored in my (PostgreSQL) database is 2013-10-07 01:00:00+08
. When I pull up this information during a python manage.py shell
session, I get 2013-10-06 17:00:00+00:00
. The same happens when I try to render this information in a template.
What I think is happening: Django recognizes that the user is entering 1:00 A.M. on October 10th, Singapore time, and stores this in the database as 2013-10-07 01:00:00+08
. However, when Django retrieves this info from the database, it formats it to UTC time, thereby giving 2013-10-06 17:00:00+00:00
.
Do I have that right? And if so, what can I do to make Django display times using the same timezone information that is stored in the database (or at least using my TIME_ZONE
setting)? In other words, how can I make it so that the user sees the datetime in the exact same form as she entered it?
The solution to this problem is to use UTC in the code and use local time only when interacting with end users. Time zone support is disabled by default. To enable it, set USE_TZ = True in your settings file. In Django 5.0, time zone support will be enabled by default.
If Server sends Date in UTC format it is automatically default to local time. That is DateTime.
Python django format date dd/mm/yyyy.
Rule #1 - STORE DATETIMES IN UTC IN YOUR DATABASE, AND BACK END CODE. It is important that there is consistency across all your date-related data. When storing dates in the database, they should always be in UTC.
I've figured out what's going on. Based on what I had read in the docs here, I was assuming that with USE_TZ=True
, Django would output datetimes in the current time zone (which defaults to the TIME_ZONE
setting) everywhere--views, the shell, etc.
However, it turns out that Django only makes the conversion in templates, and even then only in the most direct, basic invocation of a datetime
object.
Specifically, if you have an object
with a DateTimeField
and you render its datetime
attribute in a template using {{ object.datetime }}
, you will get a datetime converted to the current time zone. Yay. However, this functionality won't work for anything else, even within templates, such as {{ object.datetime.hour }}
(which will display the hour in UTC). So it's basically just an invisible template tag. Not as magical as I'd hoped!
It looks like I'll need to convert all datetimes to the current time zone in my views before passing them to my templates. I find this kind of weird and counterintuitive considering that my database already has all of the datetimes stored in the time zone I want them displayed in. Wouldn't it make more sense to have to explicitly tell Django you want database values expressed in UTC, than to have Django perform the work automatically and then make you change them back in your views?
EDIT: This answer on SO made the solution to my specific situation considerably easier:
from django.utils.timezone import localtime
result = localtime(some_time_object)
EDIT: It turns out that only PostgreSQL stores time zone information, and that information is separate from the raw datetime values it stores, which are in UTC. So I guess it makes sense for Django to render everything in UTC by default, since other database backends don't even store time zone info.
Have you looked at the localtime
template tag
update:
However that does refer to setting USE_TZ
to True
as you have
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With