+ logger.error(msg)
+ raise argparse.ArgumentTypeError(msg)
+
+
+def valid_date(txt: str) -> datetime.date:
+ """If the string is a valid date, return it. Otherwise raise
+ an ArgumentTypeError.
+
+ >>> valid_date('6/5/2021')
+ datetime.date(2021, 6, 5)
+
+ # Note: dates like 'next wednesday' work fine, they are just
+ # hard to test for without knowing when the testcase will be
+ # executed...
+ >>> valid_date('next wednesday') # doctest: +ELLIPSIS
+ -ANYTHING-
+ """
+ from string_utils import to_date
+ date = to_date(txt)
+ if date is not None:
+ return date
+ msg = f'Cannot parse argument as a date: {txt}'
+ logger.error(msg)
+ raise argparse.ArgumentTypeError(msg)
+
+
+def valid_datetime(txt: str) -> datetime.datetime:
+ """If the string is a valid datetime, return it. Otherwise raise
+ an ArgumentTypeError.
+
+ >>> valid_datetime('6/5/2021 3:01:02')
+ datetime.datetime(2021, 6, 5, 3, 1, 2)
+
+ # Again, these types of expressions work fine but are
+ # difficult to test with doctests because the answer is
+ # relative to the time the doctest is executed.
+ >>> valid_datetime('next christmas at 4:15am') # doctest: +ELLIPSIS
+ -ANYTHING-
+ """
+ from string_utils import to_datetime
+ dt = to_datetime(txt)
+ if dt is not None:
+ return dt
+ msg = f'Cannot parse argument as datetime: {txt}'
+ logger.error(msg)