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) 2017 Paul Franklin
|
||||
# Copyright (c) 2020 Steve Youngs
|
||||
#
|
||||
# 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
|
||||
@ -445,6 +446,9 @@ class DateParser:
|
||||
self._range = re.compile(
|
||||
r"(bet|bet.|between)\s+(?P<start>.+)\s+and\s+(?P<stop>.+)",
|
||||
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,
|
||||
re.IGNORECASE)
|
||||
self._modifier_after = re.compile(r'(.*)\s+%s' % self._mod_after_str,
|
||||
@ -836,6 +840,31 @@ class DateParser:
|
||||
return 1
|
||||
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):
|
||||
"""
|
||||
Try matching BCE qualifier.
|
||||
@ -923,6 +952,8 @@ class DateParser:
|
||||
return
|
||||
if self.match_range(text, cal, newyear, qual, date):
|
||||
return
|
||||
if self.match_quarter(text, cal, newyear, qual, date):
|
||||
return
|
||||
|
||||
(text, bc) = self.match_bce(text)
|
||||
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)
|
||||
|
||||
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):
|
||||
def setUp(self):
|
||||
from .. import _datestrings
|
||||
|
Loading…
Reference in New Issue
Block a user