A bunch of changes...
[python_utils.git] / dateparse / dateparse_utils.py
index f354ad09ccbefc1f3227ab7e011e7a634b37336b..21fdb832b5c556317989e4f9855dae8daae67552 100755 (executable)
@@ -1,5 +1,10 @@
 #!/usr/bin/env python3
 
+"""
+Parse dates in a variety of formats.
+
+"""
+
 import datetime
 import functools
 import holidays  # type: ignore
@@ -50,7 +55,6 @@ def debug_parse(enter_or_exit_f: Callable[[Any, Any], None]):
 class ParseException(Exception):
     """An exception thrown during parsing because of unrecognized input."""
     def __init__(self, message: str) -> None:
-        logger.error(message)
         self.message = message
 
 
@@ -59,7 +63,6 @@ class RaisingErrorListener(antlr4.DiagnosticErrorListener):
     def syntaxError(
             self, recognizer, offendingSymbol, line, column, msg, e
     ):
-        logger.error(msg)
         raise ParseException(msg)
 
     def reportAmbiguity(
@@ -251,6 +254,7 @@ class DateParser(dateparse_utilsListener):
         self.datetime: Optional[datetime.datetime] = None
         self.context: Dict[str, Any] = {}
         self.timedelta = datetime.timedelta(seconds=0)
+        self.saw_overt_year = False
 
     @staticmethod
     def _normalize_special_day_name(name: str) -> str:
@@ -302,8 +306,10 @@ class DateParser(dateparse_utilsListener):
         next_last = self.context.get('special_next_last', '')
         if next_last == 'next':
             year += 1
+            self.saw_overt_year = True
         elif next_last == 'last':
             year -= 1
+            self.saw_overt_year = True
 
         # Holiday names
         if name == 'easte':
@@ -362,6 +368,9 @@ class DateParser(dateparse_utilsListener):
             raise ParseException('Missing day')
         if 'year' not in self.context:
             self.context['year'] = self.today.year
+            self.saw_overt_year = False
+        else:
+            self.saw_overt_year = True
 
         # Handling "ides" and "nones" requires both the day and month.
         if (
@@ -612,11 +621,13 @@ class DateParser(dateparse_utilsListener):
             self.context['day'] = self.now_datetime.day
             self.context['month'] = self.now_datetime.month
             self.context['year'] = self.now_datetime.year
+            self.saw_overt_year = True
         elif txt[:4] == 'last':
             self.context['delta_int'] = -1
             self.context['day'] = self.now_datetime.day
             self.context['month'] = self.now_datetime.month
             self.context['year'] = self.now_datetime.year
+            self.saw_overt_year = True
         else:
             raise ParseException(f'Bad next/last: {ctx.getText()}')
 
@@ -845,6 +856,7 @@ class DateParser(dateparse_utilsListener):
         except Exception:
             raise ParseException(f'Bad year expression: {ctx.getText()}')
         else:
+            self.saw_overt_year = True
             self.context['year'] = year
 
     def exitSpecialDateMaybeYearExpr(