Merge pull request #1056 from stevenyoungs/dateparser_quarter
This commit is contained in:
commit
3b15423032
@ -4,6 +4,7 @@
|
|||||||
#
|
#
|
||||||
# Copyright (C) 2004-2006 Donald N. Allingham
|
# Copyright (C) 2004-2006 Donald N. Allingham
|
||||||
# Copyright (C) 2017 Paul Franklin
|
# Copyright (C) 2017 Paul Franklin
|
||||||
|
# Copyright (c) 2020 Steve Youngs
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
@ -445,6 +446,9 @@ class DateParser:
|
|||||||
self._range = re.compile(
|
self._range = re.compile(
|
||||||
r"(bet|bet.|between)\s+(?P<start>.+)\s+and\s+(?P<stop>.+)",
|
r"(bet|bet.|between)\s+(?P<start>.+)\s+and\s+(?P<stop>.+)",
|
||||||
re.IGNORECASE)
|
re.IGNORECASE)
|
||||||
|
self._quarter = re.compile(
|
||||||
|
r"[qQ](?P<quarter>[1-4])\s+(?P<year>.+)",
|
||||||
|
re.IGNORECASE)
|
||||||
self._modifier = re.compile(r'%s\s+(.*)' % self._mod_str,
|
self._modifier = re.compile(r'%s\s+(.*)' % self._mod_str,
|
||||||
re.IGNORECASE)
|
re.IGNORECASE)
|
||||||
self._modifier_after = re.compile(r'(.*)\s+%s' % self._mod_after_str,
|
self._modifier_after = re.compile(r'(.*)\s+%s' % self._mod_after_str,
|
||||||
@ -836,6 +840,31 @@ class DateParser:
|
|||||||
return 1
|
return 1
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
def match_quarter(self, text, cal, ny, qual, date):
|
||||||
|
"""
|
||||||
|
Try matching calendar quarter date.
|
||||||
|
|
||||||
|
On success, set the date and return 1. On failure return 0.
|
||||||
|
"""
|
||||||
|
match = self._quarter.match(text)
|
||||||
|
if match:
|
||||||
|
quarter = self._get_int(match.group('quarter'))
|
||||||
|
|
||||||
|
text_parser = self.parser[cal]
|
||||||
|
(text, bc) = self.match_bce(match.group('year'))
|
||||||
|
start = self._parse_subdate(text, text_parser, cal)
|
||||||
|
if (start == Date.EMPTY and text != "") or (start[0] != 0) or (start[1] != 0): # reject dates where the day or month have been set
|
||||||
|
return 0
|
||||||
|
if bc:
|
||||||
|
start = self.invert_year(start)
|
||||||
|
|
||||||
|
stop_month = quarter * 3
|
||||||
|
stop_day = _max_days[stop_month - 1] # no need to worry about leap years since no quarter ends in February
|
||||||
|
|
||||||
|
date.set(qual, Date.MOD_RANGE, cal, (1, stop_month - 2, start[2], start[3]) + (stop_day, stop_month, start[2], start[3]), newyear=ny)
|
||||||
|
return 1
|
||||||
|
return 0
|
||||||
|
|
||||||
def match_bce(self, text):
|
def match_bce(self, text):
|
||||||
"""
|
"""
|
||||||
Try matching BCE qualifier.
|
Try matching BCE qualifier.
|
||||||
@ -923,6 +952,8 @@ class DateParser:
|
|||||||
return
|
return
|
||||||
if self.match_range(text, cal, newyear, qual, date):
|
if self.match_range(text, cal, newyear, qual, date):
|
||||||
return
|
return
|
||||||
|
if self.match_quarter(text, cal, newyear, qual, date):
|
||||||
|
return
|
||||||
|
|
||||||
(text, bc) = self.match_bce(text)
|
(text, bc) = self.match_bce(text)
|
||||||
if self.match_modifier(text, cal, newyear, qual, bc, date):
|
if self.match_modifier(text, cal, newyear, qual, bc, date):
|
||||||
|
@ -77,6 +77,39 @@ class DateParserTest(unittest.TestCase):
|
|||||||
self.assert_map_key_val(self.parser.calendar_to_int, 'юлианский', Date.CAL_JULIAN)
|
self.assert_map_key_val(self.parser.calendar_to_int, 'юлианский', Date.CAL_JULIAN)
|
||||||
self.assert_map_key_val(self.parser.calendar_to_int, 'ю', Date.CAL_JULIAN)
|
self.assert_map_key_val(self.parser.calendar_to_int, 'ю', Date.CAL_JULIAN)
|
||||||
|
|
||||||
|
def test_quarter_1(self):
|
||||||
|
date = self.parser.parse('q1 1900')
|
||||||
|
self.assertTrue(date.is_equal(self.parser.parse('Q1 1900')))
|
||||||
|
self.assertEqual(date.get_ymd(), (1900, 1, 1))
|
||||||
|
self.assertEqual(date.get_stop_ymd(), (1900, 3, 31))
|
||||||
|
self.assertEqual(date.get_modifier(), Date.MOD_RANGE)
|
||||||
|
|
||||||
|
def test_quarter_2(self):
|
||||||
|
date = self.parser.parse('q2 1900')
|
||||||
|
self.assertTrue(date.is_equal(self.parser.parse('Q2 1900')))
|
||||||
|
self.assertEqual(date.get_ymd(), (1900, 4, 1))
|
||||||
|
self.assertEqual(date.get_stop_ymd(), (1900, 6, 30))
|
||||||
|
self.assertEqual(date.get_modifier(), Date.MOD_RANGE)
|
||||||
|
|
||||||
|
def test_quarter_3(self):
|
||||||
|
date = self.parser.parse('q3 1900')
|
||||||
|
self.assertTrue(date.is_equal(self.parser.parse('Q3 1900')))
|
||||||
|
self.assertEqual(date.get_ymd(), (1900, 7, 1))
|
||||||
|
self.assertEqual(date.get_stop_ymd(), (1900, 9, 30))
|
||||||
|
self.assertEqual(date.get_modifier(), Date.MOD_RANGE)
|
||||||
|
|
||||||
|
def test_quarter_4(self):
|
||||||
|
date = self.parser.parse('q4 1900')
|
||||||
|
self.assertTrue(date.is_equal(self.parser.parse('Q4 1900')))
|
||||||
|
self.assertEqual(date.get_ymd(), (1900, 10, 1))
|
||||||
|
self.assertEqual(date.get_stop_ymd(), (1900, 12, 31))
|
||||||
|
self.assertEqual(date.get_modifier(), Date.MOD_RANGE)
|
||||||
|
|
||||||
|
def test_quarter_quality_calendar(self):
|
||||||
|
date = self.parser.parse('calc q1 1900 (julian)')
|
||||||
|
self.assertEqual(date.get_quality(), Date.QUAL_CALCULATED)
|
||||||
|
self.assertEqual(date.get_calendar(), Date.CAL_JULIAN)
|
||||||
|
|
||||||
class Test_generate_variants(unittest.TestCase):
|
class Test_generate_variants(unittest.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
from .. import _datestrings
|
from .. import _datestrings
|
||||||
|
Loading…
x
Reference in New Issue
Block a user