def parse_human_datetime(human_readable: str) -> datetime: """ Returns ``datetime.datetime`` from human readable strings >>> from datetime import date, timedelta >>> from dateutil.relativedelta import relativedelta >>> parse_human_datetime('2015-04-03') datetime.datetime(2015, 4, 3, 0, 0) >>> parse_human_datetime('2/3/1969') datetime.datetime(1969, 2, 3, 0, 0) >>> parse_human_datetime('now') <= datetime.now() True >>> parse_human_datetime('yesterday') <= datetime.now() True >>> date.today() - timedelta(1) == parse_human_datetime('yesterday').date() True >>> year_ago_1 = parse_human_datetime('one year ago').date() >>> year_ago_2 = (datetime.now() - relativedelta(years=1)).date() >>> year_ago_1 == year_ago_2 True >>> year_after_1 = parse_human_datetime('2 years after').date() >>> year_after_2 = (datetime.now() + relativedelta(years=2)).date() >>> year_after_1 == year_after_2 True """ x_periods = r"^\s*([0-9]+)\s+(second|minute|hour|day|week|month|quarter|year)s?\s*$" if re.search(x_periods, human_readable, re.IGNORECASE): raise TimeRangeUnclearError(human_readable) try: default = datetime(year=datetime.now().year, month=1, day=1) dttm = parse(human_readable, default=default) except (ValueError, OverflowError) as ex: cal = parsedatetime.Calendar() parsed_dttm, parsed_flags = cal.parseDT(human_readable) # 0 == not parsed at all if parsed_flags == 0: logger.debug(ex) raise TimeRangeParseFailError(human_readable) # when time is not extracted, we 'reset to midnight' if parsed_flags & 2 == 0: parsed_dttm = parsed_dttm.replace(hour=0, minute=0, second=0) dttm = dttm_from_timetuple(parsed_dttm.utctimetuple()) return dttm
def parse_human_datetime(human_readable: str) -> datetime: """ Returns ``datetime.datetime`` from human readable strings """ x_periods = r"^\s*([0-9]+)\s+(second|minute|hour|day|week|month|quarter|year)s?\s*$" if re.search(x_periods, human_readable, re.IGNORECASE): raise TimeRangeAmbiguousError(human_readable) try: default = datetime(year=datetime.now().year, month=1, day=1) dttm = parse(human_readable, default=default) except (ValueError, OverflowError) as ex: cal = parsedatetime.Calendar() parsed_dttm, parsed_flags = cal.parseDT(human_readable) # 0 == not parsed at all if parsed_flags == 0: logger.debug(ex) raise TimeRangeParseFailError(human_readable) # when time is not extracted, we 'reset to midnight' if parsed_flags & 2 == 0: parsed_dttm = parsed_dttm.replace(hour=0, minute=0, second=0) dttm = dttm_from_timetuple(parsed_dttm.utctimetuple()) return dttm