diff --git a/mycroft/util/lang/parse_en.py b/mycroft/util/lang/parse_en.py index b3112e629a..61cb513992 100644 --- a/mycroft/util/lang/parse_en.py +++ b/mycroft/util/lang/parse_en.py @@ -14,7 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # -from datetime import datetime +from datetime import datetime, timedelta from dateutil.relativedelta import relativedelta @@ -656,29 +656,30 @@ def extract_duration_en(text): if not text: return None - time_unit_to_seconds_map = { - 'second': 1, - 'minute': 60, - 'hour': 3600, - 'day': 86400, - 'week': 604800 + time_units = { + 'microseconds': None, + 'milliseconds': None, + 'seconds': None, + 'minutes': None, + 'hours': None, + 'days': None, + 'weeks': None } pattern = r"(?P\d+(?:\.?\d+)?)\s+{unit}s?" text = _convert_words_to_numbers(text) - pieces = [] - for unit, value in time_unit_to_seconds_map.items(): - unit_pattern = pattern.format(unit=unit) + for unit in time_units: + unit_pattern = pattern.format(unit=unit[:-1]) # remove 's' from unit matches = re.findall(unit_pattern, text) - matches = map(lambda s: float(s) * value, matches) - pieces += matches + value = sum(map(float, matches)) + time_units[unit] = value text = re.sub(unit_pattern, '', text) text = text.strip() - duration = sum(pieces) + duration = timedelta(**time_units) if any(time_units.values()) else None - return (duration, text) if pieces else (None, text) + return (duration, text) def extract_datetime_en(string, dateNow, default_time): diff --git a/test/unittests/util/test_parse.py b/test/unittests/util/test_parse.py index 489be8c03c..7d2f55ddd5 100644 --- a/test/unittests/util/test_parse.py +++ b/test/unittests/util/test_parse.py @@ -15,7 +15,7 @@ # limitations under the License. # import unittest -from datetime import datetime +from datetime import datetime, timedelta from mycroft.util.parse import extract_datetime from mycroft.util.parse import extract_duration @@ -142,28 +142,39 @@ class TestNormalize(unittest.TestCase): self.assertEqual(extract_number("a couple thousand beers"), 2000) def test_extract_duration_en(self): - self.assertEqual(extract_duration("10 seconds"), (10.0, "")) - self.assertEqual(extract_duration("5 minutes"), (300.0, "")) - self.assertEqual(extract_duration("2 hours"), (7200.0, "")) - self.assertEqual(extract_duration("3 days"), (259200.0, "")) - self.assertEqual(extract_duration("25 weeks"), (15120000.0, "")) - self.assertEqual(extract_duration("seven hours"), (25200.0, "")) - self.assertEqual(extract_duration("7.5 seconds"), (7.5, "")) + self.assertEqual(extract_duration("10 seconds"), + (timedelta(seconds=10.0), "")) + self.assertEqual(extract_duration("5 minutes"), + (timedelta(minutes=5), "")) + self.assertEqual(extract_duration("2 hours"), + (timedelta(hours=2), "")) + self.assertEqual(extract_duration("3 days"), + (timedelta(days=3), "")) + self.assertEqual(extract_duration("25 weeks"), + (timedelta(weeks=25), "")) + self.assertEqual(extract_duration("seven hours"), + (timedelta(hours=7), "")) + self.assertEqual(extract_duration("7.5 seconds"), + (timedelta(seconds=7.5), "")) self.assertEqual(extract_duration("eight and a half days thirty" - " nine seconds"), (734439.0, "")) + " nine seconds"), + (timedelta(days=8.5, seconds=39), "")) self.assertEqual(extract_duration("Set a timer for 30 minutes"), - (1800.0, "set a timer for")) + (timedelta(minutes=30), "set a timer for")) self.assertEqual(extract_duration("Four and a half minutes until" - " sunset"), (270.0, "until sunset")) + " sunset"), + (timedelta(minutes=4.5), "until sunset")) self.assertEqual(extract_duration("Nineteen minutes past the hour"), - (1140.0, "past the hour")) + (timedelta(minutes=19), "past the hour")) self.assertEqual(extract_duration("wake me up in three weeks, four" " hundred ninety seven days, and" " three hundred 91.6 seconds"), - (44755591.6, "wake me up in , , and")) + (timedelta(weeks=3, days=497, seconds=391.6), + "wake me up in , , and")) self.assertEqual(extract_duration("The movie is one hour, fifty seven" " and a half minutes long"), - (7050.0, "the movie is , long")) + (timedelta(hours=1, minutes=57.5), + "the movie is , long")) def test_extractdatetime_en(self): def extractWithFormat(text):