Merge pull request #1266 from hrbonz/date_timezone

Change date metadata parsing to dateutil.parser
This commit is contained in:
Justin Mayer 2014-03-31 16:36:23 -07:00
commit cfd18b20fc
4 changed files with 37 additions and 38 deletions

View file

@ -130,6 +130,8 @@ automatically installed without any action on your part:
utilities utilities
* `MarkupSafe <http://pypi.python.org/pypi/MarkupSafe>`_, for a markup safe * `MarkupSafe <http://pypi.python.org/pypi/MarkupSafe>`_, for a markup safe
string implementation string implementation
* `python-dateutil <https://pypi.python.org/pypi/python-dateutil>`_, to read
the date metadata
If you want the following optional packages, you will need to install them If you want the following optional packages, you will need to install them
manually via ``pip``: manually via ``pip``:

View file

@ -41,6 +41,12 @@ class TestUtils(LoggedTestCase):
date = datetime.datetime(year=2012, month=11, day=22) date = datetime.datetime(year=2012, month=11, day=22)
date_hour = datetime.datetime( date_hour = datetime.datetime(
year=2012, month=11, day=22, hour=22, minute=11) year=2012, month=11, day=22, hour=22, minute=11)
date_hour_z = datetime.datetime(
year=2012, month=11, day=22, hour=22, minute=11,
tzinfo=pytz.timezone('UTC'))
date_hour_est = datetime.datetime(
year=2012, month=11, day=22, hour=22, minute=11,
tzinfo=pytz.timezone('EST'))
date_hour_sec = datetime.datetime( date_hour_sec = datetime.datetime(
year=2012, month=11, day=22, hour=22, minute=11, second=10) year=2012, month=11, day=22, hour=22, minute=11, second=10)
date_hour_sec_z = datetime.datetime( date_hour_sec_z = datetime.datetime(
@ -61,22 +67,42 @@ class TestUtils(LoggedTestCase):
'22/11/2012': date, '22/11/2012': date,
'22.11.2012': date, '22.11.2012': date,
'22.11.2012 22:11': date_hour, '22.11.2012 22:11': date_hour,
'2012-11-22T22:11Z': date_hour_z,
'2012-11-22T22:11-0500': date_hour_est,
'2012-11-22 22:11:10': date_hour_sec, '2012-11-22 22:11:10': date_hour_sec,
'2012-11-22T22:11:10Z': date_hour_sec_z, '2012-11-22T22:11:10Z': date_hour_sec_z,
'2012-11-22T22:11:10-0500': date_hour_sec_est, '2012-11-22T22:11:10-0500': date_hour_sec_est,
'2012-11-22T22:11:10.123Z': date_hour_sec_frac_z, '2012-11-22T22:11:10.123Z': date_hour_sec_frac_z,
} }
# examples from http://www.w3.org/TR/NOTE-datetime
iso_8601_date = datetime.datetime(year=1997, month=7, day=16)
iso_8601_date_hour_tz = datetime.datetime(
year=1997, month=7, day=16, hour=19, minute=20,
tzinfo=pytz.timezone('CET'))
iso_8601_date_hour_sec_tz = datetime.datetime(
year=1997, month=7, day=16, hour=19, minute=20, second=30,
tzinfo=pytz.timezone('CET'))
iso_8601_date_hour_sec_ms_tz = datetime.datetime(
year=1997, month=7, day=16, hour=19, minute=20, second=30,
microsecond=450000, tzinfo=pytz.timezone('CET'))
iso_8601 = {
'1997-07-16': iso_8601_date,
'1997-07-16T19:20+01:00': iso_8601_date_hour_tz,
'1997-07-16T19:20:30+01:00': iso_8601_date_hour_sec_tz,
'1997-07-16T19:20:30.45+01:00': iso_8601_date_hour_sec_ms_tz,
}
# invalid ones # invalid ones
invalid_dates = ['2010-110-12', 'yay'] 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(): for value, expected in dates.items():
self.assertEqual(utils.get_date(value), expected, value) self.assertEqual(utils.get_date(value), expected, value)
for value, expected in iso_8601.items():
self.assertEqual(utils.get_date(value), expected, value)
for item in invalid_dates: for item in invalid_dates:
self.assertRaises(ValueError, utils.get_date, item) self.assertRaises(ValueError, utils.get_date, item)

View file

@ -15,7 +15,7 @@ import traceback
from collections import Hashable from collections import Hashable
from contextlib import contextmanager from contextlib import contextmanager
from datetime import datetime import dateutil.parser
from functools import partial from functools import partial
from itertools import groupby from itertools import groupby
from jinja2 import Markup from jinja2 import Markup
@ -181,39 +181,10 @@ def get_date(string):
If no format matches the given date, raise a ValueError. If no format matches the given date, raise a ValueError.
""" """
string = re.sub(' +', ' ', string) string = re.sub(' +', ' ', string)
formats = [ try:
# ISO 8601 return dateutil.parser.parse(string)
'%Y', except (TypeError, ValueError):
'%Y-%m', raise ValueError('{0!r} is not a valid date'.format(string))
'%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))
@contextmanager @contextmanager

View file

@ -2,7 +2,7 @@
from setuptools import setup from setuptools import setup
requires = ['feedgenerator >= 1.6', 'jinja2 >= 2.7', 'pygments', 'docutils', requires = ['feedgenerator >= 1.6', 'jinja2 >= 2.7', 'pygments', 'docutils',
'pytz >= 0a', 'blinker', 'unidecode', 'six'] 'pytz >= 0a', 'blinker', 'unidecode', 'six', 'python-dateutil']
entry_points = { entry_points = {
'console_scripts': [ 'console_scripts': [