diff --git a/gramps/gen/datehandler/_date_cs.py b/gramps/gen/datehandler/_date_cs.py index d89ff1c08..610470f40 100644 --- a/gramps/gen/datehandler/_date_cs.py +++ b/gramps/gen/datehandler/_date_cs.py @@ -50,6 +50,12 @@ class DateParserCZ(DateParser): Converts a text string into a Date object """ + modifier_to_int = { + 'před': Date.MOD_BEFORE, + 'kolem': Date.MOD_ABOUT, + 'po': Date.MOD_AFTER, + } + quality_to_int = { 'přibližně' : Date.QUAL_ESTIMATED, 'odhadem' : Date.QUAL_ESTIMATED, diff --git a/gramps/gen/datehandler/_date_da.py b/gramps/gen/datehandler/_date_da.py index e7d7565a0..0446aade8 100644 --- a/gramps/gen/datehandler/_date_da.py +++ b/gramps/gen/datehandler/_date_da.py @@ -66,6 +66,7 @@ class DateParserDa(DateParser): calendar_to_int = { 'gregoriansk ' : Date.CAL_GREGORIAN, 'g' : Date.CAL_GREGORIAN, + 'juliansk tidsregning': Date.CAL_JULIAN, 'juliansk' : Date.CAL_JULIAN, 'j' : Date.CAL_JULIAN, 'hebraisk' : Date.CAL_HEBREW, @@ -84,6 +85,7 @@ class DateParserDa(DateParser): quality_to_int = { 'estimeret' : Date.QUAL_ESTIMATED, + 'anslået' : Date.QUAL_ESTIMATED, 'beregnet' : Date.QUAL_CALCULATED, } diff --git a/gramps/gen/datehandler/_date_hu.py b/gramps/gen/datehandler/_date_hu.py index ab17f3ab8..119b1cfae 100644 --- a/gramps/gen/datehandler/_date_hu.py +++ b/gramps/gen/datehandler/_date_hu.py @@ -192,7 +192,7 @@ class DateParserHU(DateParser): # month_to_int["Karácsony hava"] = 12 # month_to_int["Álom hava"] = 12 - modifier_after_to_int={ + modifier_to_int = { 'előtt' : Date.MOD_BEFORE, 'körül' : Date.MOD_ABOUT, 'után' : Date.MOD_AFTER, @@ -215,6 +215,7 @@ class DateParserHU(DateParser): calendar_to_int = { 'Gergely' : Date.CAL_GREGORIAN, 'Julián' : Date.CAL_JULIAN, + 'julián' : Date.CAL_JULIAN, 'héber' : Date.CAL_HEBREW, 'iszlám' : Date.CAL_ISLAMIC, 'francia köztársasági' : Date.CAL_FRENCH, diff --git a/gramps/gen/datehandler/_date_is.py b/gramps/gen/datehandler/_date_is.py index 9f3af4424..f8dec9392 100644 --- a/gramps/gen/datehandler/_date_is.py +++ b/gramps/gen/datehandler/_date_is.py @@ -60,7 +60,8 @@ class DateParserIs(DateParser): 'á undan' : Date.MOD_BEFORE, 'eftir' : Date.MOD_AFTER, 'í kringum' : Date.MOD_ABOUT, - 'uþb' : Date.MOD_ABOUT + 'uþb' : Date.MOD_ABOUT, + 'um' : Date.MOD_ABOUT, } bce = ["f Kr"] diff --git a/gramps/gen/datehandler/_date_ja.py b/gramps/gen/datehandler/_date_ja.py index 16d5a2458..14c4a3d03 100644 --- a/gramps/gen/datehandler/_date_ja.py +++ b/gramps/gen/datehandler/_date_ja.py @@ -54,8 +54,8 @@ class DateParserJA(DateParser): converted, the text string is assigned. """ - # modifiers before the date - modifier_to_int = { + # modifiers after the date + modifier_after_to_int = { '以前' : Date.MOD_BEFORE, '以降' : Date.MOD_AFTER, '頃' : Date.MOD_ABOUT, @@ -68,6 +68,7 @@ class DateParserJA(DateParser): 'およそ' : Date.QUAL_ESTIMATED, 'ごろ' : Date.QUAL_ESTIMATED, '位' : Date.QUAL_ESTIMATED, + 'の見積り' : Date.QUAL_ESTIMATED, '計算上' : Date.QUAL_CALCULATED, } @@ -163,16 +164,20 @@ class DateParserJA(DateParser): }) _span_1 = ['から', '~', '〜'] - _span_2 = ['まで', ''] + _span_2 = ['まで'] _range_1 = ['から', 'と', '~', '〜'] _range_2 = ['までの間', 'の間'] - self._span = re.compile(r"(?P.+)(%s)(?P\d+)(%s)" % + self._span = re.compile(r"(?P.+)(%s)(?P.+)(%s)" % ('|'.join(_span_1), '|'.join(_span_2)), re.IGNORECASE) self._range = re.compile(r"(?P.+)(%s)(?P.+)(%s)" % ('|'.join(_range_1), '|'.join(_range_2)), re.IGNORECASE) self._numeric = re.compile(r"((\d+)年\s*)?((\d+)月\s*)?(\d+)?日?\s*$") + self._cal = re.compile(r"(.*?)\s*\(%s\)\s*(.*)" % self._cal_str, + re.IGNORECASE) + self._qual = re.compile(r"(.*?)\s*%s\s*(.*)" % self._qual_str, + re.IGNORECASE) #------------------------------------------------------------------------- # diff --git a/gramps/gen/datehandler/_date_pt.py b/gramps/gen/datehandler/_date_pt.py index 4d55153d0..330fe63c9 100644 --- a/gramps/gen/datehandler/_date_pt.py +++ b/gramps/gen/datehandler/_date_pt.py @@ -91,11 +91,13 @@ class DateParserPT(DateParser): quality_to_int = { 'estimado' : Date.QUAL_ESTIMATED, + 'estimada' : Date.QUAL_ESTIMATED, 'est.' : Date.QUAL_ESTIMATED, 'est' : Date.QUAL_ESTIMATED, 'calc.' : Date.QUAL_CALCULATED, 'calc' : Date.QUAL_CALCULATED, 'calculado' : Date.QUAL_CALCULATED, + 'calculada' : Date.QUAL_CALCULATED, } def init_strings(self): diff --git a/gramps/gen/datehandler/_date_sr.py b/gramps/gen/datehandler/_date_sr.py index c134601d7..b30e6fd0f 100644 --- a/gramps/gen/datehandler/_date_sr.py +++ b/gramps/gen/datehandler/_date_sr.py @@ -195,8 +195,10 @@ class DateParserSR(DateParser): 'процењено' : Date.QUAL_ESTIMATED, 'про.' : Date.QUAL_ESTIMATED, + 'приближно' : Date.QUAL_ESTIMATED, 'израчунато' : Date.QUAL_CALCULATED, 'изр.' : Date.QUAL_CALCULATED, + 'прорачунато': Date.QUAL_CALCULATED, } bce = ["пре нове ере", "пре Христа", "п.н.е." @@ -215,7 +217,7 @@ class DateParserSR(DateParser): self._numeric = re.compile( r"((\d+)[/\. ])?\s*((\d+)[/\.])?\s*(\d+)\.?$") - _span_1 = ['od', 'од'] + _span_1 = ['od', 'од', 'из'] _span_2 = ['do', 'до'] _range_1 = ['između', 'између'] _range_2 = ['i', 'и'] diff --git a/gramps/gen/datehandler/_date_zh_CN.py b/gramps/gen/datehandler/_date_zh_CN.py index 98ec011ec..bffe0e560 100644 --- a/gramps/gen/datehandler/_date_zh_CN.py +++ b/gramps/gen/datehandler/_date_zh_CN.py @@ -124,11 +124,12 @@ class DateParserZH_CN(DateParser): _span_2 = ['至'] _range_1 = ['介于'] _range_2 = ['与'] - self._span = re.compile(r"(%s)(?P.+)(%s)(?P\d+)" % + _range_3 = ['之间'] + self._span = re.compile(r"(%s)\s*(?P.+)\s*(%s)\s*(?P.+)" % ('|'.join(_span_1), '|'.join(_span_2)), re.IGNORECASE) - self._range = re.compile(r"(%s)(?P.+)(%s)(?P\d+)" % - ('|'.join(_range_1), '|'.join(_range_2)), + self._range = re.compile(r"(%s)\s*(?P.+)\s*(%s)\s*(?P.+)\s*(%s)" % + ('|'.join(_range_1), '|'.join(_range_2), '|'.join(_range_3)), re.IGNORECASE) self._numeric = re.compile(r"((\d+)年\s*)?((\d+)月\s*)?(\d+)?日?\s*$") diff --git a/gramps/gen/datehandler/_date_zh_TW.py b/gramps/gen/datehandler/_date_zh_TW.py index da3935108..fbfdfc383 100644 --- a/gramps/gen/datehandler/_date_zh_TW.py +++ b/gramps/gen/datehandler/_date_zh_TW.py @@ -124,11 +124,12 @@ class DateParserZH_TW(DateParser): _span_2 = ['至'] _range_1 = ['介於'] _range_2 = ['與'] - self._span = re.compile(r"(%s)(?P.+)(%s)(?P\d+)" % + _range_3 = ['之間'] + self._span = re.compile(r"(%s)\s*(?P.+)\s*(%s)\s*(?P.+)" % ('|'.join(_span_1), '|'.join(_span_2)), re.IGNORECASE) - self._range = re.compile(r"(%s)(?P.+)(%s)(?P\d+)" % - ('|'.join(_range_1), '|'.join(_range_2)), + self._range = re.compile(r"(%s)\s*(?P.+)\s*(%s)\s*(?P.+)\s*(%s)" % + ('|'.join(_range_1), '|'.join(_range_2), '|'.join(_range_3)), re.IGNORECASE) self._numeric = re.compile(r"((\d+)年\s*)?((\d+)月\s*)?(\d+)?日?\s*$") diff --git a/gramps/gen/datehandler/_dateparser.py b/gramps/gen/datehandler/_dateparser.py index 27265d23e..4dc5ea8b0 100644 --- a/gramps/gen/datehandler/_dateparser.py +++ b/gramps/gen/datehandler/_dateparser.py @@ -308,13 +308,13 @@ class DateParser: _langs = set() def __init_prefix_tables(self): + ds = self._ds = DateStrings(self._locale) lang = self._locale.lang if lang in DateParser._langs: log.debug("Prefix tables for {} already built".format(lang)) return else: DateParser._langs.add(lang) - ds = self._ds = DateStrings(self._locale) log.debug("Begin building parser prefix tables for {}".format(lang)) _build_prefix_table(DateParser.month_to_int, _generate_variants( diff --git a/gramps/gen/datehandler/test/datehandler_test.py b/gramps/gen/datehandler/test/datehandler_test.py index 9779d7b0f..e75d51923 100644 --- a/gramps/gen/datehandler/test/datehandler_test.py +++ b/gramps/gen/datehandler/test/datehandler_test.py @@ -5,6 +5,8 @@ # Copyright (C) 2000-2006 Martin Hawlisch, Donald N. Allingham # Copyright (C) 2008 Brian G. Matherly # Copyright (C) 2010 Jakim Friant +# Copyright (C) 2022 Jan Skarvall +# Copyright (C) 2022 Nick Hall # # 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 @@ -46,9 +48,10 @@ if '-v' in sys.argv or '--verbose' in sys.argv: # Gramps modules # #------------------------------------------------------------------------- +from ...config import config from ...lib import Date, DateError -from .. import parser as _dp -from .. import displayer as _dd +from ...utils.grampslocale import GrampsLocale, _LOCALE_NAMES +from .. import LANG_TO_PARSER #------------------------------------------------------------------------- # @@ -56,14 +59,31 @@ from .. import displayer as _dd # #------------------------------------------------------------------------- class DateHandlerTest(unittest.TestCase): - def base_case(self, test_date): - datestr = _dd.display(test_date) - new_date = _dp.parse(datestr) - self.assertTrue(test_date.is_equal(new_date), - "{} -> {}\n{} -> {}".format( - test_date, new_date, - test_date.__dict__, new_date.__dict__)) + def setUp(self): + config.set('preferences.date-format', 0) + + def __base_test_all_languages(self, dates): + + languages = [lang for lang in LANG_TO_PARSER.keys() + if lang in _LOCALE_NAMES.keys()] + for language in languages: + with self.subTest(lang=language): + self.__test_language(language, dates) + + def __test_language(self, language, dates): + + locale = GrampsLocale(lang=language) + displayer = locale.date_displayer + parser = locale.date_parser + for test_date in dates: + datestr = displayer.display(test_date) + new_date = parser.parse(datestr) + with self.subTest(date=datestr): + self.assertTrue(test_date.is_equal(new_date), + "{} -> {}\n{} -> {}".format( + test_date, new_date, + test_date.__dict__, new_date.__dict__)) def test_simple(self): @@ -75,7 +95,7 @@ class DateHandlerTest(unittest.TestCase): for modifier in (Date.MOD_NONE, Date.MOD_BEFORE, Date.MOD_AFTER, Date.MOD_ABOUT): for slash1 in (False,True): - for month in range(1, 13): + for month in (2, 6, 12): for day in (5, 27): d = Date() d.set(quality, modifier, calendar, @@ -83,9 +103,7 @@ class DateHandlerTest(unittest.TestCase): "Text comment", newyear) dates.append(d) - - for test_date in dates: - self.base_case(test_date) + self.__base_test_all_languages(dates) def test_span(self): @@ -96,7 +114,7 @@ class DateHandlerTest(unittest.TestCase): for modifier in (Date.MOD_RANGE, Date.MOD_SPAN): for slash1 in (False, True): for slash2 in (False, True): - for month in range(1, 13): + for month in (2, 6, 12): for day in (5, 27): d = Date() d.set(quality, modifier, calendar, @@ -122,11 +140,11 @@ class DateHandlerTest(unittest.TestCase): 32-day, 13-month, 1876, slash2), "Text comment") dates.append(d) - - for test_date in dates: - self.base_case(test_date) + self.__base_test_all_languages(dates) def test_textual(self): + + dates = [] calendar = Date.CAL_GREGORIAN modifier = Date.MOD_TEXTONLY for quality in (Date.QUAL_NONE, Date.QUAL_ESTIMATED, @@ -134,7 +152,8 @@ class DateHandlerTest(unittest.TestCase): test_date = Date() test_date.set(quality, modifier, calendar, Date.EMPTY, "This is a textual date") - self.base_case(test_date) + dates.append(test_date) + self.__base_test_all_languages(dates) def test_too_few_arguments(self): dateval = (4, 7, 1789, False)