Use datetime.timedelta for extract_duration_en.

This is in support of issues-1959.
pull/1977/head
Chris Rogers 2019-02-03 12:16:36 -05:00
parent d50cb00de8
commit cdf7dc3756
2 changed files with 40 additions and 28 deletions

View File

@ -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<value>\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):

View File

@ -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):