I understand that the best practice now with Django 1.4 is to store all datetime
in UTC and I agree with that. I also understand that all timezone conversation should be done in the template level like this:
{% load tz %}
{% timezone "Europe/Paris" %}
Paris time: {{ value }}
{% endtimezone %}
However, I need to convert the UTC time to the request
's local time all in Python. I can't use the template tags since I am returning the string in JSON using Ajax (more specifically Dajaxice).
Currently this is my code ajax.py
:
# checked is from the checkbox's this.value (Javascript).
datetime = timezone.now() if checked else None
$ order_pk is sent to the Ajax function.
order = Order.objects.get(pk=order_pk)
order.time = datetime
order.save()
return simplejson.dumps({
'error': False,
'datetime': dateformat.format(datetime, 'F j, Y, P') if checked else 'None'
})
So even if the current time is April 14, 2012, 5:52 p.m.
in EST time (my local timezone), the JSON response will return April 14, 2012, 9:52 p.m
, because that is the UTC time.
Also I noticed that Django stores a template variable called TIME_ZONE
for each request (not actually part of the request
variable), so since my is America/New_York
, I'm assuming that Django can figure out each visitor's own local timezone (based on HTTP header)?
Anyway, so my question is two-fold:
ajax.py
? (Probably pass it as a string argument like {{ TIME_ZONE }}
)timezone.now()
to the local timezone and output as a string using Django's dateformat
?EDIT: for @agf
timezone.now()
gives the UTC time when USE_TZ = True
:
# From django.utils.timezone
def now():
"""
Returns an aware or naive datetime.datetime, depending on settings.USE_TZ.
"""
if settings.USE_TZ:
# timeit shows that datetime.now(tz=utc) is 24% slower
return datetime.utcnow().replace(tzinfo=utc)
else:
return datetime.now()
Is there anyway to convert a datetime
to something other than UTC? For example, can I do something like current_time = timezone.now()
, then current_time.replace(tzinfo=est)
(EST = Eastern Standard Time)?
To enable it, set USE_TZ = True in your settings file. In Django 5.0, time zone support will be enabled by default. Time zone support uses zoneinfo , which is part of the Python standard library from Python 3.9.
You can get the current time in a particular timezone by using the datetime module with another module called pytz . You can then check for all available timezones with the snippet below: from datetime import datetime import pytz zones = pytz. all_timezones print(zones) # Output: all timezones of the world.
TIME_ZONE in Django The default timezone is TIME_ZONE = 'UTC' . TIME_ZONE = 'Asia/Calcutta' . For applying these changes we need to set the USE_TZ variable to TRUE.
You need to read the Django Timezones docs carefully.
One important point:
there's no equivalent of the Accept-Language HTTP header that Django could use to determine the user's time zone automatically.
You have to ask the user what their timezone is or just use a default.
You also need to make sure:
USE_TZ = True
in your settings.py
.
Once you have a timezone tz
, you can:
from django.utils import timezone
timezone.activate(tz)
datetime = timezone.now() if checked else None
to get a timezone-aware datetime
object in timezone tz
.
While the browser does not send any headers to the server that would indicate a timezone, the JavaScript environment does know its current timezone.
This has two important effects: While the server can't find out your current timezone on the initial request, you can send down some javascript code which will determine the TZ offset and send that information back to the server so that the zone info can be associated with the current session from that point forward.
But more importantly, if you're sending your time value inside JSON data which will be interpreted by the browser client-side, the browser's timezone doesn't need to be known. Instead, you only have to ensure the timezone offset is present in your JSON output so that the browser can do its own timezone math after-the-fact.
var now = new Date()
var offset_minutes = now.getTimezoneOffset() # e.g. 240 for GMT-0400
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