Repository: MycroftAI/lingua-franca

Issue:
extract_datetime() returns 8 AM results in utterance where no time specification was made
forslund has backtracked this to lingua franca in [mycroft-core issue #2647](https://github.com/MycroftAI/mycroft-core/issues/2647)

> Found this while reworking the skill-reminder. While processing non timed reminder there is a safeguard mechanism to check [extract_datetime](https://github.com/MycroftAI/mycroft-core/blob/a6cb0c5258dbc34e7f80daf50ed751c87a40c61e/mycroft/util/parse.py#L145) in ["the case where padatious misses the time/date"](https://github.com/MycroftAI/skill-reminder/blob/b8dc13ec00bb0feb361deb58fd71080e98ed1325/__init__.py#L251) with the result of returning 8 AM and blocking the non timed reminder alltogether. (tested in german language. Phrase: "Erinnere mich an Meeting"; changed the vocab locally and tested it also with "Erinnere mich Meeting" with no difference)

-------------------

> Seems to be a german (or non-english) issue in lingua franca:
> 
> Mycroft calls:
> 
> from mycroft.util.parse import extract_datetime
> print(extract_datetime('Remind me of the meeting', lang='en-us'))
> None
> print(extract_datetime('Remind me of the meeting', lang='de-de'))
> [datetime.datetime(2020, 8, 5, 0, 0, tzinfo=tzfile('/usr/share/zoneinfo/Europe/Stockholm')), 'remind me of the meeting']
> 
> Lingua franca calls:
> 
> from lingua_franca.parse import extract_datetime
> print(extract_datetime('Remind me of the meeting', lang='en-us'))
> None
> print(extract_datetime('Remind me of the meeting', lang='de-de'))
> [datetime.datetime(2020, 8, 5, 0, 0, tzinfo=tzlocal()), 'remind me of the meeting']

Comments:

Patch:
diff --git a/lingua_franca/lang/parse_da.py b/lingua_franca/lang/parse_da.py
index 76bca9c..e513b47 100644
--- a/lingua_franca/lang/parse_da.py
+++ b/lingua_franca/lang/parse_da.py
@@ -733,7 +733,7 @@ def extract_datetime_da(string, currentDate, default_time):
             found = True
 
     # check that we found a date
-    if not date_found:
+    if not date_found():
         return None
 
     if dayOffset is False:
diff --git a/lingua_franca/lang/parse_de.py b/lingua_franca/lang/parse_de.py
index 4f21c54..9f6d447 100644
--- a/lingua_franca/lang/parse_de.py
+++ b/lingua_franca/lang/parse_de.py
@@ -745,7 +745,7 @@ def extract_datetime_de(string, currentDate, default_time):
             found = True
 
     # check that we found a date
-    if not date_found:
+    if not date_found():
         return None
 
     if dayOffset is False:
diff --git a/lingua_franca/lang/parse_es.py b/lingua_franca/lang/parse_es.py
index 66dfbd6..536f980 100644
--- a/lingua_franca/lang/parse_es.py
+++ b/lingua_franca/lang/parse_es.py
@@ -993,7 +993,7 @@ def extract_datetime_es(input_str, currentDate=None, default_time=None):
             found = True
 
     # check that we found a date
-    if not date_found:
+    if not date_found():
         return None
 
     if dayOffset is False:
diff --git a/lingua_franca/lang/parse_nl.py b/lingua_franca/lang/parse_nl.py
index eb909e0..a656779 100644
--- a/lingua_franca/lang/parse_nl.py
+++ b/lingua_franca/lang/parse_nl.py
@@ -1305,7 +1305,7 @@ def extract_datetime_nl(string, dateNow, default_time):
             idx += used - 1
             found = True
     # check that we found a date
-    if not date_found:
+    if not date_found():
         return None
 
     if dayOffset is False:
diff --git a/lingua_franca/lang/parse_sv.py b/lingua_franca/lang/parse_sv.py
index 1a6e0ec..af34e9a 100644
--- a/lingua_franca/lang/parse_sv.py
+++ b/lingua_franca/lang/parse_sv.py
@@ -653,7 +653,7 @@ def extract_datetime_sv(string, currentDate, default_time):
             found = True
 
     # check that we found a date
-    if not date_found:
+    if not date_found():
         return None
 
     if dayOffset is False:


Test patch:
diff --git a/test/test_parse_da.py b/test/test_parse_da.py
index 8342a99..8dfddb5 100644
--- a/test/test_parse_da.py
+++ b/test/test_parse_da.py
@@ -71,7 +71,7 @@ class TestNormalize(unittest.TestCase):
 #        self.assertEqual(extract_number("tre fjerdedel kop", lang="da-dk"),
 #                         3.0 / 4.0)
 
-    def test_extractdatetime_de(self):
+    def test_extractdatetime_da(self):
         def extractWithFormat(text):
             date = datetime(2017, 6, 27, 0, 0)
             [extractedDate, leftover] = extract_datetime(text, date,
@@ -158,6 +158,10 @@ class TestNormalize(unittest.TestCase):
 #        testExtract("lad os mødes klokken 8:00 om aftenen",
 #                    "2017-06-27 20:00:00", "lad os mødes")
 
+    def test_extractdatetime_no_time(self):
+        """Check that None is returned if no time is found in sentence."""
+        self.assertEqual(extract_datetime('ingen tid', lang='da-da'), None)
+
     def test_extractdatetime_default_da(self):
         default = time(9, 0, 0)
         anchor = datetime(2017, 6, 27, 0, 0)
diff --git a/test/test_parse_de.py b/test/test_parse_de.py
index 1a10f0a..e0d097c 100644
--- a/test/test_parse_de.py
+++ b/test/test_parse_de.py
@@ -159,6 +159,10 @@ class TestNormalize(unittest.TestCase):
         testExtract("lass uns treffen um 8:00 abends",
                     "2017-06-27 20:00:00", "lass uns treffen")
 
+    def test_extractdatetime_no_time(self):
+        """Check that None is returned if no time is found in sentence."""
+        self.assertEqual(extract_datetime('kein zeit', lang='de-de'), None)
+
     def test_extractdatetime_default_de(self):
         default = time(9, 0, 0)
         anchor = datetime(2017, 6, 27, 0, 0)
diff --git a/test/test_parse_es.py b/test/test_parse_es.py
index 355554e..a597cdb 100644
--- a/test/test_parse_es.py
+++ b/test/test_parse_es.py
@@ -202,10 +202,6 @@ class TestDatetime_es(unittest.TestCase):
             "ayer por la tarde", anchorDate=datetime(1998, 1, 1),
             lang='es')[0], datetime(1997, 12, 31, 15))
 
-        self.assertEqual(extract_datetime(
-            "qué año es", anchorDate=datetime(1998, 1, 1),
-            lang='es')[0], datetime(1998, 1, 1))
-
         self.assertEqual(extract_datetime("hoy 2 de la mañana", lang='es',
                                           anchorDate=datetime(1998, 1, 1))[0],
                          datetime(1998, 1, 1, 2))
@@ -213,6 +209,10 @@ class TestDatetime_es(unittest.TestCase):
                                           anchorDate=datetime(1998, 1, 1))[0],
                          datetime(1998, 1, 1, 14))
 
+    def test_extractdatetime_no_time(self):
+        """Check that None is returned if no time is found in sentence."""
+        self.assertEqual(extract_datetime('no hay tiempo', lang='es-es'), None)
+
     @unittest.skip("These phrases are not parsing correctly.")
     def test_extract_datetime_relative_failing(self):
         # parses as "morning" and returns 8:00 on anchorDate
diff --git a/test/test_parse_nl.py b/test/test_parse_nl.py
index fe2148f..edd3ec7 100644
--- a/test/test_parse_nl.py
+++ b/test/test_parse_nl.py
@@ -146,6 +146,10 @@ class TestParsing(unittest.TestCase):
                                anchor, lang=LANG, default_time=default)
         self.assertEqual(default, res[0].time())
 
+    def test_extractdatetime_no_time(self):
+        """Check that None is returned if no time is found in sentence."""
+        self.assertEqual(extract_datetime('geen tijd', lang=LANG), None)
+
     def test_spaces(self):
         self.assertEqual(normalize("  dit   is  een    test", LANG),
                          "dit is 1 test")
diff --git a/test/test_parse_sv.py b/test/test_parse_sv.py
index d577bed..c5e02cd 100644
--- a/test/test_parse_sv.py
+++ b/test/test_parse_sv.py
@@ -97,6 +97,10 @@ class TestNormalize(unittest.TestCase):
                                anchor, lang='sv-se', default_time=default)
         self.assertEqual(default, res[0].time())
 
+    def test_extractdatetime_no_time(self):
+        """Check that None is returned if no time is found in sentence."""
+        self.assertEqual(extract_datetime('Ingen tid', lang='sv-se'), None)
+
     def test_numbers(self):
         self.assertEqual(normalize("det här är ett ett två tre  test",
                                    lang='sv-se'),