diff options
author | Aarni Koskela <akx@iki.fi> | 2022-01-27 17:09:39 +0200 |
---|---|---|
committer | Aarni Koskela <akx@iki.fi> | 2022-01-28 11:07:08 +0200 |
commit | 7aee5b8ff1c911322a9615e911b3bd205259aa00 (patch) | |
tree | f181e65c1e1a5e8220f8b4f8fdc891033031d3da | |
parent | d3cea2adda7688e56a3cbfbfe98f8003a299a56e (diff) | |
download | babel-7aee5b8ff1c911322a9615e911b3bd205259aa00.tar.gz |
Improve partial time parsing
Refs #442
Co-authored-by: David Bauer <david.bauer009@gmail.com>
Co-authored-by: Arthur Jovart <arthur@jovart.com>
-rw-r--r-- | babel/dates.py | 22 | ||||
-rw-r--r-- | tests/test_dates.py | 23 |
2 files changed, 37 insertions, 8 deletions
diff --git a/babel/dates.py b/babel/dates.py index f94c60a..4c14ea2 100644 --- a/babel/dates.py +++ b/babel/dates.py @@ -1206,14 +1206,24 @@ def parse_time(string, locale=LC_TIME): indexes.sort() indexes = dict([(item[1], idx) for idx, item in enumerate(indexes)]) - # FIXME: support 12 hour clock, and 0-based hour specification - # and seconds should be optional, maybe minutes too - # oh, and time-zones, of course + # TODO: support time zones + + # Check if the format specifies a period to be used; + # if it does, look for 'pm' to figure out an offset. + hour_offset = 0 + if 'a' in format: + if 'pm' in string.lower(): + hour_offset = 12 numbers = re.findall(r'(\d+)', string) - hour = int(numbers[indexes['H']]) - minute = int(numbers[indexes['M']]) - second = int(numbers[indexes['S']]) + + # Parse up to three numbers from the string. + minute = second = 0 + hour = int(numbers[indexes['H']]) + hour_offset + if len(numbers) > 1: + minute = int(numbers[indexes['M']]) + if len(numbers) > 2: + second = int(numbers[indexes['S']]) return time(hour, minute, second) diff --git a/tests/test_dates.py b/tests/test_dates.py index d11758c..d85fd08 100644 --- a/tests/test_dates.py +++ b/tests/test_dates.py @@ -777,8 +777,27 @@ def test_parse_date(): assert dates.parse_date('01.04.2004', locale='de_DE') == date(2004, 4, 1) -def test_parse_time(): - assert dates.parse_time('15:30:00', locale='en_US') == time(15, 30) +@pytest.mark.parametrize('input, expected', [ + # base case, fully qualified time + ('15:30:00', time(15, 30)), + # test digits + ('15:30', time(15, 30)), + ('3:30', time(3, 30)), + ('00:30', time(0, 30)), + # test am parsing + ('03:30 am', time(3, 30)), + ('3:30:21 am', time(3, 30, 21)), + ('3:30 am', time(3, 30)), + # test pm parsing + ('03:30 pm', time(15, 30)), + ('03:30 pM', time(15, 30)), + ('03:30 Pm', time(15, 30)), + ('03:30 PM', time(15, 30)), + # test hour-only parsing + ('4 pm', time(16, 0)), +]) +def test_parse_time(input, expected): + assert dates.parse_time(input, locale='en_US') == expected def test_datetime_format_get_week_number(): |