Skip to content

Instantly share code, notes, and snippets.

@moreati
Last active March 5, 2022 11:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save moreati/5a64bd9779a2a0832058f376cfe00ad3 to your computer and use it in GitHub Desktop.
Save moreati/5a64bd9779a2a0832058f376cfe00ad3 to your computer and use it in GitHub Desktop.
Hacky wrapper for dateparser.parse() that handles christmas and new year
import datetime
import re
import dateparser
def fudge_datetime(s: str, now: datetime.datetime = None) -> datetime.datetime:
"""
Return a best guess datetime for the free-form string s, relative to now.
>>> fudge_datetime("Christmas Day 2020")
datetime.datetime(2020, 12, 25, 23, 59, 59)
>>> fudge_datetime("yesterday", now=datetime.datetime(2020, 2, 28, 12, 00)
datetime.datetime(2020, 2, 27, 23, 59, 59)
Assumptions:
- the date/time in `s` occurs before the date/time `now`
"""
# TODO Timezones
wip = s
# Replace references to holidays with dates
# TODO Easter
holidays = {
"christmas eve": "24 December",
"christmas day": "25 December",
"boxing day": "26 December",
"new year's eve": "31 December",
"new years eve": "31 December",
"new year's day": "1 January",
"new years day": "1 January",
}
holiday_patt = re.compile(
# NB Relies on Python 3.6+ stable dict ordering
r'|'.join(re.escape(holiday) for holiday in holidays),
flags=re.IGNORECASE,
)
def holiday_repl(m: re.Match) -> str:
holiday = m.group(0).lower()
return holidays[holiday]
wip = holiday_patt.sub(holiday_repl, wip)
last_patt = re.compile(r'^last\s+', flags=re.IGNORECASE)
wip = last_patt.sub('', wip)
dt = dateparser.parse(wip)
if dt is None:
raise ValueError(repr(s))
# Initialise this *after* parsing, so the sanity check passes for s=='today'
if now is None:
now = datetime.datetime.now()
if dt > now:
raise ValueError(f'{s=!r} {dt=} {now=}')
# If s contained time information, use it
if dt.time() > datetime.time(0):
return dt
return dt.replace(hour=23, minute=59, second=59)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment