From cc7e4fda85491a2f82cd4e74a12c11cf165e4b8d Mon Sep 17 00:00:00 2001 From: Paul Franklin Date: Wed, 26 Sep 2018 14:04:52 -0700 Subject: [PATCH] [unhandled exception parsing "future dates" in some locales] There is already a check in the MonitoredDate class for years which are more than one year in the future, so such a date is already going to be shown in red. But some locales use the "datetime" library to parse typed-in dates and that has a maximum year of datetime.MAXYEAR, 9999 currently, so dates greater than that produce a ValueError. Besides adding checks for that, I have also made it so that locales which don't need that library don't use it. Fixes #10815 --- gramps/gen/datehandler/_date_is.py | 3 ++- gramps/gen/datehandler/_datedisplay.py | 28 ++++++++++++++++---------- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/gramps/gen/datehandler/_date_is.py b/gramps/gen/datehandler/_date_is.py index d2ba32c36..9f3af4424 100644 --- a/gramps/gen/datehandler/_date_is.py +++ b/gramps/gen/datehandler/_date_is.py @@ -186,7 +186,8 @@ class DateDisplayIs(DateDisplay): text, scal) def _get_weekday(self, date_val): - if date_val[0] == 0 or date_val[1] == 0: # no day or no month or both + if (date_val[0] == 0 or date_val[1] == 0 # no day or no month or both + or date_val[2] > datetime.MAXYEAR): # bug 10815 return '' w_day = datetime.date(date_val[2], date_val[1], date_val[0]) # y, m, d return self.short_days[((w_day.weekday() + 1) % 7) + 1] diff --git a/gramps/gen/datehandler/_datedisplay.py b/gramps/gen/datehandler/_datedisplay.py index abdf3eeb7..3baafec62 100644 --- a/gramps/gen/datehandler/_datedisplay.py +++ b/gramps/gen/datehandler/_datedisplay.py @@ -4,7 +4,7 @@ # # Copyright (C) 2004-2006 Donald N. Allingham # Copyright (C) 2013 Vassilii Khachaturov -# Copyright (C) 2014-2017 Paul Franklin +# Copyright (C) 2014-2018 Paul Franklin # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -570,6 +570,7 @@ class DateDisplay: def _get_short_weekday(self, date_val): if (date_val[0] == 0 or date_val[1] == 0 # no day or no month or both or date_val[1] == 13 # Hebrew has 13 months + or date_val[2] > datetime.MAXYEAR # bug 10815 or date_val[2] < 0): # B.C.E. date return '' w_day = datetime.date(date_val[2], date_val[1], date_val[0]) # y, m, d @@ -578,6 +579,7 @@ class DateDisplay: def _get_long_weekday(self, date_val): if (date_val[0] == 0 or date_val[1] == 0 # no day or no month or both or date_val[1] == 13 # Hebrew has 13 months + or date_val[2] > datetime.MAXYEAR # bug 10815 or date_val[2] < 0): # B.C.E. date return '' w_day = datetime.date(date_val[2], date_val[1], date_val[0]) # y, m, d @@ -597,16 +599,20 @@ class DateDisplay: return str(date_val[2]) else: value = self.dhformat.replace('%m', str(date_val[1])) - # some locales have %b for the month, e.g. ar_EG, is_IS, nb_NO - # so it would be "Jan" but as it's "numeric" I'll make it "1" - value = value.replace('%b', str(date_val[1])) - # some locales have %B for the month, e.g. ta_IN - # so it would be "January" but as it's "numeric" I'll make it 1 - value = value.replace('%B', str(date_val[1])) - # some locales have %a for the abbreviated day, e.g. is_IS - value = value.replace('%a', self._get_short_weekday(date_val)) - # some locales have %A for the long/full day, e.g. ta_IN - value = value.replace('%A', self._get_long_weekday(date_val)) + if '%b' in value or '%B' in value: + # some locales have %b for the month (ar_EG, is_IS, nb_NO) + # so it would be "Jan" but as it's "numeric" make it "1" + value = value.replace('%b', str(date_val[1])) + # some locales have %B for the month, e.g. ta_IN + # so it would be "January" but as it's "numeric" make it 1 + value = value.replace('%B', str(date_val[1])) + if '%a' in value or '%A' in value: + # some locales have %a for the abbreviated day, e.g. is_IS + value = value.replace('%a', + self._get_short_weekday(date_val)) + # some locales have %A for the long/full day, e.g. ta_IN + value = value.replace('%A', + self._get_long_weekday(date_val)) if date_val[0] == 0: # ignore the zero day and its delimiter i_day = value.find('%d') if len(value) == i_day + 2: # delimiter is left of the day