diff --git a/django/contrib/syndication/feeds.py b/django/contrib/syndication/feeds.py index 15513faa35..ade43d7cff 100644 --- a/django/contrib/syndication/feeds.py +++ b/django/contrib/syndication/feeds.py @@ -145,7 +145,7 @@ class Feed(object): author_email = author_link = None pubdate = self.__get_dynamic_attr('item_pubdate', item) - if pubdate: + if pubdate and not pubdate.tzinfo: now = datetime.now() utcnow = datetime.utcnow() diff --git a/tests/regressiontests/syndication/feeds.py b/tests/regressiontests/syndication/feeds.py index eabc1f94a8..79837f9459 100644 --- a/tests/regressiontests/syndication/feeds.py +++ b/tests/regressiontests/syndication/feeds.py @@ -1,6 +1,7 @@ from django.core.exceptions import ObjectDoesNotExist from django.contrib.syndication import feeds from django.utils.feedgenerator import Atom1Feed +from django.utils import tzinfo class ComplexFeed(feeds.Feed): def get_object(self, bits): @@ -46,3 +47,20 @@ class MyCustomAtom1Feed(Atom1Feed): class TestCustomFeed(TestAtomFeed): feed_type = MyCustomAtom1Feed + +class NaiveDatesFeed(TestAtomFeed): + """ + A feed with naive (non-timezone-aware) dates. + """ + def item_pubdate(self, item): + return item.date + +class TZAwareDatesFeed(TestAtomFeed): + """ + A feed with timezone-aware dates. + """ + def item_pubdate(self, item): + # Provide a weird offset so that the test can know it's getting this + # specific offset and not accidentally getting on from + # settings.TIME_ZONE. + return item.date.replace(tzinfo=tzinfo.FixedOffset(42)) \ No newline at end of file diff --git a/tests/regressiontests/syndication/tests.py b/tests/regressiontests/syndication/tests.py index 1410ed7517..816cb44675 100644 --- a/tests/regressiontests/syndication/tests.py +++ b/tests/regressiontests/syndication/tests.py @@ -1,8 +1,10 @@ # -*- coding: utf-8 -*- +import datetime from xml.dom import minidom from django.test import TestCase from django.test.client import Client +from django.utils import tzinfo from models import Entry try: set @@ -91,4 +93,27 @@ class SyndicationFeedTest(TestCase): link = item.getElementsByTagName('link')[0] if link.firstChild.wholeText == 'http://example.com/blog/4/': title = item.getElementsByTagName('title')[0] - self.assertEquals(title.firstChild.wholeText, u'A & B < C > D') \ No newline at end of file + self.assertEquals(title.firstChild.wholeText, u'A & B < C > D') + + def test_naive_datetime_conversion(self): + """ + Test that datetimes are correctly converted to the local time zone. + """ + # Naive date times passed in get converted to the local time zone, so + # check the recived zone offset against the local offset. + response = self.client.get('/syndication/feeds/naive-dates/') + doc = minidom.parseString(response.content) + updated = doc.getElementsByTagName('updated')[0].firstChild.wholeText + tz = tzinfo.LocalTimezone(datetime.datetime.now()) + now = datetime.datetime.now(tz) + self.assertEqual(updated[-6:], str(now)[-6:]) + + def test_aware_datetime_conversion(self): + """ + Test that datetimes with timezones don't get trodden on. + """ + response = self.client.get('/syndication/feeds/aware-dates/') + doc = minidom.parseString(response.content) + updated = doc.getElementsByTagName('updated')[0].firstChild.wholeText + self.assertEqual(updated[-6:], '+00:42') + \ No newline at end of file diff --git a/tests/regressiontests/syndication/urls.py b/tests/regressiontests/syndication/urls.py index f37222d9b5..ec45026fc4 100644 --- a/tests/regressiontests/syndication/urls.py +++ b/tests/regressiontests/syndication/urls.py @@ -1,12 +1,13 @@ -from feeds import TestRssFeed, TestAtomFeed, TestCustomFeed, ComplexFeed +import feeds from django.conf.urls.defaults import patterns feed_dict = { - 'complex': ComplexFeed, - 'rss': TestRssFeed, - 'atom': TestAtomFeed, - 'custom': TestCustomFeed, - + 'complex': feeds.ComplexFeed, + 'rss': feeds.TestRssFeed, + 'atom': feeds.TestAtomFeed, + 'custom': feeds.TestCustomFeed, + 'naive-dates': feeds.NaiveDatesFeed, + 'aware-dates': feeds.TZAwareDatesFeed, } urlpatterns = patterns('', (r'^feeds/(?P.*)/$', 'django.contrib.syndication.views.feed', {'feed_dict': feed_dict})