From d49d82305fb8441062cf66667a477fb04055a996 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 13 May 2012 17:24:34 +0530 Subject: [PATCH] utility function to generate datetime from date strings such that the year and month are always correct --- src/calibre/ebooks/metadata/sources/amazon.py | 4 ++-- src/calibre/utils/date.py | 20 +++++++++++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/calibre/ebooks/metadata/sources/amazon.py b/src/calibre/ebooks/metadata/sources/amazon.py index 4ff4726139..6764e2f6f7 100644 --- a/src/calibre/ebooks/metadata/sources/amazon.py +++ b/src/calibre/ebooks/metadata/sources/amazon.py @@ -18,7 +18,7 @@ from calibre.ebooks.metadata import check_isbn from calibre.ebooks.metadata.sources.base import (Source, Option, fixcase, fixauthors) from calibre.ebooks.metadata.book.base import Metadata -from calibre.utils.date import parse_date +from calibre.utils.date import parse_only_date from calibre.utils.localization import canonicalize_lang class Worker(Thread): # Get details {{{ @@ -471,7 +471,7 @@ class Worker(Thread): # Get details {{{ ans = x.tail date = ans.rpartition('(')[-1].replace(')', '').strip() date = self.delocalize_datestr(date) - return parse_date(date, assume_utc=True) + return parse_only_date(date, assume_utc=True) def parse_language(self, pd): for x in reversed(pd.xpath(self.language_xpath)): diff --git a/src/calibre/utils/date.py b/src/calibre/utils/date.py index 8741cb6a9e..e269683ee3 100644 --- a/src/calibre/utils/date.py +++ b/src/calibre/utils/date.py @@ -82,6 +82,26 @@ def parse_date(date_string, assume_utc=False, as_utc=True, default=None): dt = dt.replace(tzinfo=_utc_tz if assume_utc else _local_tz) return dt.astimezone(_utc_tz if as_utc else _local_tz) +def parse_only_date(raw, assume_utc=True): + ''' + Parse a date string that contains no time information in a manner that + guarantees that the month and year are always correct in all timezones, and + the day is at most one day wrong. + ''' + from calibre.utils.date import utcnow, now, parse_date + from datetime import timedelta + f = utcnow if assume_utc else now + default = f().replace(hour=0, minute=0, second=0, microsecond=0, + day=15) + ans = parse_date(raw, default=default, assume_utc=assume_utc) + n = ans + timedelta(days=1) + if n.month > ans.month: + ans = ans.replace(day=ans.day-1) + if ans.day == 1: + ans = ans.replace(day=2) + return ans + + def strptime(val, fmt, assume_utc=False, as_utc=True): dt = datetime.strptime(val, fmt) if dt.tzinfo is None: