I have a meeting model with a start time column:
class Meeting(mode.Model):
name = models.CharField(max_length=100)
start = models.DateTimeField()
My time zone is set to TIME_ZONE = 'America/Toronto'
I'm currently entering the EDT value of the time. In my template, I want to display both the EDT and PDT values, for example:
| Name | Start |
| First Meeting | 10:00 AM PDT |
| | 1:00 PM EDT |
Is it c开发者_JS百科urrently possible in Django to display two different timezone values from a single entry?
Depends how you want it to render. I'd make a templatetag, and then you could put things like {{ start_time|pdt_edt }}
. The benefit of this method over defining functions in the class objects is that you can reuse the filter for other datetimes that need to be printed in both formats. (E.g., if your meeting had an end time; or another object had a time that you'd like to list in both formats).
I'd suggest starting with pytz to handle (install easy_install.py pytz
).
Basically make a sub-directory of your app called templatetags/
put in an __init__.py
and another file call it something say time_zone_display.py
for your template tag. (Basic procedure
In your template include
{% load time_zone_display %}
...
{{ start_time|pdt_edt }}
And in time_zone_display.py
something like
from django import template
from django.utils.safestring import mark_safe
from datetime import datetime, time
register = template.Library()
@register.filter
def pdt_edt(some_date):
if type(some_date) not in (datetime, time):
return "Template ERROR: Not a datetime"
else:
your_time = pytz.timezone(settings.TIME_ZONE)
d = your_time.localize(some_date)
pdt = pytz.timezone('US/Pacific')
edt = pytz.timezone('US/Eastern')
d_pdt = d.astimezone(pdt).strftime('%I:%M %p %Z')
d_edt = d.astimezone(edt).strftime('%I:%M %p %Z')
return mark_safe("%s<br />%s" % (d_pdt, d_edt))
You could also simplify the template if you know that your settings.TIME_ZONE will always be a fixed offset (3 hours) from pacific time, so then you could just do something like:
from django import template
from django.utils.safestring import mark_safe
from datetime import datetime, time, timedelta
register = template.Library()
@register.filter
def pdt_edt(some_date):
if type(some_date) not in (datetime, time):
return "Template ERROR: Not a datetime"
else:
d_edt = some_date.strftime("%H:%M %p EDT")
d_pdt = (some_date - timedelta(0,3*60*60)).strftime("%H:%M %p PDT")
return mark_safe("%s<br />%s" % (d_pdt, d_edt))
(Though EDT/PDT are only the correct abbreviations during daylight's savings time; so the first method is better thought it requires installing pytz).
EDIT: the rare case when Eastern time and pacific time are not off by three hours, but pytz will handle correctly.
>>> from datetime import datetime
>>> import pytz
>>> ptz = pytz.timezone('US/Pacific')
>>> etz = pytz.timezone('US/Eastern')
>>> d = datetime(2011,3,13, 3, 30) # 3:30 am on March 13th,2011 when daylights savings started this year
>>> print d.astimezone(etz).strftime('%m/%d/%Y %I:%M %p %z')
03/13/2011 03:30 AM EDT
>>> print d.astimezone(ptz).strftime('%m/%d/%Y %I:%M %p %z')
03/12/2011 11:30 PM PST
You can create a function in your model that calculates PDT time from EDT time and use it in your template like any other field of your model:
class Meeting(models.Model)
name = models.CharField(max_length=100)
start = models.DateTimeField()
def start_PDT(self):
# example using 'pytz' module
# `start` is already in EDT timezone
PDT = pytz.timezone('US/Pacific')
return self.start.astimezone(pytz.PDT)
In the template:
{{ meeting.start_PDT }}
精彩评论