Skip to content

Commit 7aee5b8

Browse files
akxDBauer15paris-ci
committed
Improve partial time parsing
Refs #442 Co-authored-by: David Bauer <david.bauer009@gmail.com> Co-authored-by: Arthur Jovart <arthur@jovart.com>
1 parent d3cea2a commit 7aee5b8

2 files changed

Lines changed: 37 additions & 8 deletions

File tree

babel/dates.py

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1206,14 +1206,24 @@ def parse_time(string, locale=LC_TIME):
12061206
indexes.sort()
12071207
indexes = dict([(item[1], idx) for idx, item in enumerate(indexes)])
12081208

1209-
# FIXME: support 12 hour clock, and 0-based hour specification
1210-
# and seconds should be optional, maybe minutes too
1211-
# oh, and time-zones, of course
1209+
# TODO: support time zones
1210+
1211+
# Check if the format specifies a period to be used;
1212+
# if it does, look for 'pm' to figure out an offset.
1213+
hour_offset = 0
1214+
if 'a' in format:
1215+
if 'pm' in string.lower():
1216+
hour_offset = 12
12121217

12131218
numbers = re.findall(r'(\d+)', string)
1214-
hour = int(numbers[indexes['H']])
1215-
minute = int(numbers[indexes['M']])
1216-
second = int(numbers[indexes['S']])
1219+
1220+
# Parse up to three numbers from the string.
1221+
minute = second = 0
1222+
hour = int(numbers[indexes['H']]) + hour_offset
1223+
if len(numbers) > 1:
1224+
minute = int(numbers[indexes['M']])
1225+
if len(numbers) > 2:
1226+
second = int(numbers[indexes['S']])
12171227
return time(hour, minute, second)
12181228

12191229

tests/test_dates.py

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -777,8 +777,27 @@ def test_parse_date():
777777
assert dates.parse_date('01.04.2004', locale='de_DE') == date(2004, 4, 1)
778778

779779

780-
def test_parse_time():
781-
assert dates.parse_time('15:30:00', locale='en_US') == time(15, 30)
780+
@pytest.mark.parametrize('input, expected', [
781+
# base case, fully qualified time
782+
('15:30:00', time(15, 30)),
783+
# test digits
784+
('15:30', time(15, 30)),
785+
('3:30', time(3, 30)),
786+
('00:30', time(0, 30)),
787+
# test am parsing
788+
('03:30 am', time(3, 30)),
789+
('3:30:21 am', time(3, 30, 21)),
790+
('3:30 am', time(3, 30)),
791+
# test pm parsing
792+
('03:30 pm', time(15, 30)),
793+
('03:30 pM', time(15, 30)),
794+
('03:30 Pm', time(15, 30)),
795+
('03:30 PM', time(15, 30)),
796+
# test hour-only parsing
797+
('4 pm', time(16, 0)),
798+
])
799+
def test_parse_time(input, expected):
800+
assert dates.parse_time(input, locale='en_US') == expected
782801

783802

784803
def test_datetime_format_get_week_number():

0 commit comments

Comments
 (0)