diff --git a/pelican/contents.py b/pelican/contents.py index 19c07e71..64f2480f 100644 --- a/pelican/contents.py +++ b/pelican/contents.py @@ -9,17 +9,14 @@ import functools import os import re import sys -import pytz from datetime import datetime - - from pelican import signals from pelican.settings import DEFAULT_CONFIG from pelican.utils import (slugify, truncate_html_words, memoized, strftime, python_2_unicode_compatible, deprecated_attribute, - path_to_url) + path_to_url, set_date_tzinfo) # Import these so that they're avalaible when you import from pelican.contents. from pelican.urlwrappers import (URLWrapper, Author, Category, Tag) # NOQA @@ -108,13 +105,15 @@ class Content(object): locale.setlocale(locale.LC_ALL, locale_string) self.date_format = self.date_format[1] + #Give valid timezone for date object if hasattr(self, 'date'): self.locale_date = strftime(self.date, self.date_format) - #Set UTC timezone - if self.date.tzinfo is not None: - local_tz = pytz.timezone(settings['TIMEZONE']) - self.date = self.date.replace(tzinfo=local_tz) - self.utcdate = datetime.astimezone(self.date, pytz.timezone("UTC")) + if hasattr(self, 'timezone'): + set_date_tzinfo(self.date,self.timezone) + elif 'TIMEZONE' in self.settings: + set_date_tzinfo(self.date, settings['TIMEZONE']) + else: + set_date_tzinfo(self.date,'UTC') # manage status if not hasattr(self, 'status'): diff --git a/pelican/tests/test_utils.py b/pelican/tests/test_utils.py index 0e65003a..09d67ce7 100644 --- a/pelican/tests/test_utils.py +++ b/pelican/tests/test_utils.py @@ -17,7 +17,6 @@ from pelican.settings import read_settings from pelican import utils from .support import get_article, LoggedTestCase, locale_available, unittest - class TestUtils(LoggedTestCase): _new_attribute = 'new_value' @@ -70,15 +69,12 @@ class TestUtils(LoggedTestCase): # invalid ones invalid_dates = ['2010-110-12', 'yay'] - if version_info < (3, 2): - dates.pop('2012-11-22T22:11:10-0500') - invalid_dates.append('2012-11-22T22:11:10-0500') - for value, expected in dates.items(): self.assertEqual(utils.get_date(value), expected, value) - for item in invalid_dates: - self.assertRaises(ValueError, utils.get_date, item) + for date in invalid_dates: + self.assertRaises(ValueError, utils.get_date, date) + def test_slugify(self): @@ -238,6 +234,8 @@ class TestUtils(LoggedTestCase): self.assertEqual(utils.strftime(d, '%d/%m/%y'), '29/08/12') self.assertEqual(utils.strftime(d, '%d/%m/%Y'), '29/08/2012') + # RFC 339 Test + self.assertEqual(utils.strftime(d, '%Y-%m-%dT%H:%M:%SZ'),'2012-08-29T00:00:00Z') # % escaped self.assertEqual(utils.strftime(d, '%d%%%m%%%y'), '29%08%12') self.assertEqual(utils.strftime(d, '%d %% %m %% %y'), '29 % 08 % 12') diff --git a/pelican/utils.py b/pelican/utils.py index b1524036..2b37992b 100644 --- a/pelican/utils.py +++ b/pelican/utils.py @@ -19,6 +19,7 @@ from datetime import datetime from itertools import groupby from jinja2 import Markup from operator import attrgetter +from dateutil import parser logger = logging.getLogger(__name__) @@ -179,40 +180,44 @@ def get_date(string): If no format matches the given date, raise a ValueError. """ - string = re.sub(' +', ' ', string) - formats = [ - # ISO 8601 - '%Y', - '%Y-%m', - '%Y-%m-%d', - '%Y-%m-%dT%H:%M%z', - '%Y-%m-%dT%H:%MZ', - '%Y-%m-%dT%H:%M', - '%Y-%m-%dT%H:%M:%S%z', - '%Y-%m-%dT%H:%M:%SZ', - '%Y-%m-%dT%H:%M:%S', - '%Y-%m-%dT%H:%M:%S.%f%z', - '%Y-%m-%dT%H:%M:%S.%fZ', - '%Y-%m-%dT%H:%M:%S.%f', - # end ISO 8601 forms - '%Y-%m-%d %H:%M', - '%Y-%m-%d %H:%M:%S', - '%Y/%m/%d %H:%M', - '%Y/%m/%d', - '%d-%m-%Y', - '%d.%m.%Y %H:%M', - '%d.%m.%Y', - '%d/%m/%Y', - ] - for date_format in formats: - try: - date = datetime.strptime(string, date_format) - except ValueError: - continue - if date_format.endswith('Z'): - date = date.replace(tzinfo=pytz.timezone('UTC')) - return date - raise ValueError('{0!r} is not a valid date'.format(string)) + #string = re.sub(' +', ' ', string) + #formats = [ + # # ISO 8601 + # '%Y', + # '%Y-%m', + # '%Y-%m-%d', + # '%Y-%m-%dT%H:%M%z', + # '%Y-%m-%dT%H:%MZ', + # '%Y-%m-%dT%H:%M', + # '%Y-%m-%dT%H:%M:%S%z', + # '%Y-%m-%dT%H:%M:%SZ', + # '%Y-%m-%dT%H:%M:%S', + # '%Y-%m-%dT%H:%M:%S.%f%z', + # '%Y-%m-%dT%H:%M:%S.%fZ', + # '%Y-%m-%dT%H:%M:%S.%f', + # # end ISO 8601 forms + # '%Y-%m-%d %H:%M', + # '%Y-%m-%d %H:%M:%S', + # '%Y/%m/%d %H:%M', + # '%Y/%m/%d', + # '%d-%m-%Y', + # '%d.%m.%Y %H:%M', + # '%d.%m.%Y', + # '%d/%m/%Y', + # ] + #for date_format in formats: + # try: + # date = datetime.strptime(string, date_format) + # except ValueError: + # continue + # if date_format.endswith('Z'): + # date = date.replace(tzinfo=pytz.timezone('UTC')) + # return date + #raise ValueError('{0!r} is not a valid date'.format(string)) + try: + return parser.parse(string) + except ValueError: + raise ValueError('{0!r} is not a valid date'.format(string)) class pelican_open(object):