Fixed #12998 -- Corrected handling of time zones in syndication framework.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@12791 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Russell Keith-Magee 2010-03-15 15:25:39 +00:00
parent 2d57300f52
commit e89a5e06cf
2 changed files with 22 additions and 20 deletions

View File

@ -158,21 +158,8 @@ class Feed(object):
pubdate = self.__get_dynamic_attr('item_pubdate', item) pubdate = self.__get_dynamic_attr('item_pubdate', item)
if pubdate and not pubdate.tzinfo: if pubdate and not pubdate.tzinfo:
now = datetime.datetime.now() ltz = tzinfo.LocalTimezone(pubdate)
utcnow = datetime.datetime.utcnow() pubdate = pubdate.replace(tzinfo=ltz)
# Must always subtract smaller time from larger time here.
if utcnow > now:
sign = -1
tzDifference = (utcnow - now)
else:
sign = 1
tzDifference = (now - utcnow)
# Round the timezone offset to the nearest half hour.
tzOffsetMinutes = sign * ((tzDifference.seconds / 60 + 15) / 30) * 30
tzOffset = datetime.timedelta(minutes=tzOffsetMinutes)
pubdate = pubdate.replace(tzinfo=tzinfo.FixedOffset(tzOffset))
feed.add_item( feed.add_item(
title = title, title = title,

View File

@ -3,6 +3,7 @@ from django.contrib.syndication import feeds, views
from django.core.exceptions import ImproperlyConfigured from django.core.exceptions import ImproperlyConfigured
from django.test import TestCase from django.test import TestCase
from django.utils import tzinfo from django.utils import tzinfo
from django.utils.feedgenerator import rfc2822_date, rfc3339_date
from models import Entry from models import Entry
from xml.dom import minidom from xml.dom import minidom
@ -55,13 +56,19 @@ class SyndicationFeedTest(FeedTestCase):
chan_elem = feed.getElementsByTagName('channel') chan_elem = feed.getElementsByTagName('channel')
self.assertEqual(len(chan_elem), 1) self.assertEqual(len(chan_elem), 1)
chan = chan_elem[0] chan = chan_elem[0]
# Find the last build date
d = Entry.objects.latest('date').date
ltz = tzinfo.LocalTimezone(d)
last_build_date = rfc2822_date(d.replace(tzinfo=ltz))
self.assertChildNodes(chan, ['title', 'link', 'description', 'language', 'lastBuildDate', 'item', 'atom:link', 'ttl', 'copyright', 'category']) self.assertChildNodes(chan, ['title', 'link', 'description', 'language', 'lastBuildDate', 'item', 'atom:link', 'ttl', 'copyright', 'category'])
self.assertChildNodeContent(chan, { self.assertChildNodeContent(chan, {
'title': 'My blog', 'title': 'My blog',
'description': 'A more thorough description of my blog.', 'description': 'A more thorough description of my blog.',
'link': 'http://example.com/blog/', 'link': 'http://example.com/blog/',
'language': 'en', 'language': 'en',
'lastBuildDate': 'Thu, 03 Jan 2008 13:30:00 -0600', 'lastBuildDate': last_build_date,
#'atom:link': '', #'atom:link': '',
'ttl': '600', 'ttl': '600',
'copyright': 'Copyright (c) 2007, Sally Smith', 'copyright': 'Copyright (c) 2007, Sally Smith',
@ -80,6 +87,11 @@ class SyndicationFeedTest(FeedTestCase):
'http://example.com/syndication/rss2/' 'http://example.com/syndication/rss2/'
) )
# Find the pubdate of the first feed item
d = Entry.objects.get(pk=1).date
ltz = tzinfo.LocalTimezone(d)
pub_date = rfc2822_date(d.replace(tzinfo=ltz))
items = chan.getElementsByTagName('item') items = chan.getElementsByTagName('item')
self.assertEqual(len(items), Entry.objects.count()) self.assertEqual(len(items), Entry.objects.count())
self.assertChildNodeContent(items[0], { self.assertChildNodeContent(items[0], {
@ -87,7 +99,7 @@ class SyndicationFeedTest(FeedTestCase):
'description': 'Overridden description: My first entry', 'description': 'Overridden description: My first entry',
'link': 'http://example.com/blog/1/', 'link': 'http://example.com/blog/1/',
'guid': 'http://example.com/blog/1/', 'guid': 'http://example.com/blog/1/',
'pubDate': 'Tue, 01 Jan 2008 12:30:00 -0600', 'pubDate': pub_date,
'author': 'test@example.com (Sally Smith)', 'author': 'test@example.com (Sally Smith)',
}) })
self.assertCategories(items[0], ['python', 'testing']); self.assertCategories(items[0], ['python', 'testing']);
@ -198,9 +210,12 @@ class SyndicationFeedTest(FeedTestCase):
response = self.client.get('/syndication/naive-dates/') response = self.client.get('/syndication/naive-dates/')
doc = minidom.parseString(response.content) doc = minidom.parseString(response.content)
updated = doc.getElementsByTagName('updated')[0].firstChild.wholeText updated = doc.getElementsByTagName('updated')[0].firstChild.wholeText
tz = tzinfo.LocalTimezone(datetime.datetime.now())
now = datetime.datetime.now(tz) d = Entry.objects.latest('date').date
self.assertEqual(updated[-6:], str(now)[-6:]) ltz = tzinfo.LocalTimezone(d)
latest = rfc3339_date(d.replace(tzinfo=ltz))
self.assertEqual(updated, latest)
def test_aware_datetime_conversion(self): def test_aware_datetime_conversion(self):
""" """