From 866574a85442a0310fbc2bf06b6fbf1d759d1479 Mon Sep 17 00:00:00 2001
From: Jacob Kaplan-Moss <jacob@jacobian.org>
Date: Tue, 7 Apr 2009 21:21:17 +0000
Subject: [PATCH] [1.0.X] Fixed #9957: feeds now respect time zone information
 provided by the pub date. Backport of r10435 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.0.X@10436 bcc190cf-cafb-0310-a4f2-bffc1f526a37
---
 django/contrib/syndication/feeds.py        |  2 +-
 tests/regressiontests/syndication/feeds.py | 18 +++++++++++++++
 tests/regressiontests/syndication/tests.py | 27 +++++++++++++++++++++-
 tests/regressiontests/syndication/urls.py  | 13 ++++++-----
 4 files changed, 52 insertions(+), 8 deletions(-)

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 &amp; B &lt; C &gt; D')
\ No newline at end of file
+                self.assertEquals(title.firstChild.wholeText, u'A &amp; B &lt; C &gt; 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<url>.*)/$', 'django.contrib.syndication.views.feed', {'feed_dict': feed_dict})