Dont use dateutil to parse dates known to be in the ISO 8601 format

dateutils parse() method is unstable, with behavior changes in minor
releases that break parsing of ISO 8601 dates
This commit is contained in:
Kovid Goyal 2016-06-04 11:15:59 +05:30
parent 1cfe7a6f3c
commit fb97ed4ee4
3 changed files with 13 additions and 9 deletions

View File

@ -16,10 +16,10 @@ from calibre import isbytestring
# Translate datetimes to and from strings. The string form is the datetime in # Translate datetimes to and from strings. The string form is the datetime in
# UTC. The returned date is also UTC # UTC. The returned date is also UTC
def string_to_datetime(src): def string_to_datetime(src):
from calibre.utils.date import parse_date from calibre.utils.iso8601 import parse_iso8601
if src != "None": if src != "None":
try: try:
return parse_date(src) return parse_iso8601(src)
except Exception: except Exception:
pass pass
return None return None

View File

@ -377,8 +377,8 @@ def from_json(obj):
if obj['__class__'] == 'bytearray': if obj['__class__'] == 'bytearray':
return bytearray(base64.standard_b64decode(obj['__value__'])) return bytearray(base64.standard_b64decode(obj['__value__']))
if obj['__class__'] == 'datetime.datetime': if obj['__class__'] == 'datetime.datetime':
from calibre.utils.date import parse_date from calibre.utils.iso8601 import parse_iso8601
return parse_date(obj['__value__'], assume_utc=True) return parse_iso8601(obj['__value__'], assume_utc=True)
return obj return obj
class JSONConfig(XMLConfig): class JSONConfig(XMLConfig):

View File

@ -14,8 +14,8 @@ from lxml import etree
from lxml.builder import ElementMaker from lxml.builder import ElementMaker
from calibre import force_unicode from calibre import force_unicode
from calibre.utils.date import parse_date, now as nowf, utcnow, local_tz, \ from calibre.utils.iso8601 import parse_iso8601
isoformat, fromordinal from calibre.utils.date import now as nowf, utcnow, local_tz, isoformat, fromordinal, UNDEFINED_DATE
from calibre.utils.recycle_bin import delete_file from calibre.utils.recycle_bin import delete_file
NS = 'http://calibre-ebook.com/recipe_collection' NS = 'http://calibre-ebook.com/recipe_collection'
@ -292,8 +292,8 @@ class SchedulerConfig(object):
ld = x.get('last_downloaded', None) ld = x.get('last_downloaded', None)
if ld and last_downloaded is None: if ld and last_downloaded is None:
try: try:
last_downloaded = parse_date(ld) last_downloaded = parse_iso8601(ld)
except: except Exception:
pass pass
self.root.remove(x) self.root.remove(x)
break break
@ -397,7 +397,11 @@ class SchedulerConfig(object):
days = list(map(int, [x.strip() for x in days = list(map(int, [x.strip() for x in
parts[0].split(',')])) parts[0].split(',')]))
sch = [days, int(parts[1]), int(parts[2])] sch = [days, int(parts[1]), int(parts[2])]
return typ, sch, parse_date(recipe.get('last_downloaded')) try:
ld = parse_iso8601(recipe.get('last_downloaded'))
except Exception:
ld = UNDEFINED_DATE
return typ, sch, ld
def recipe_needs_to_be_downloaded(self, recipe): def recipe_needs_to_be_downloaded(self, recipe):
try: try: