1
0
personal-data/personal_data/parse_util.py

85 lines
2.4 KiB
Python

import datetime
DATETIME_UNITS = {
'second': datetime.timedelta(seconds=1),
'seconds': datetime.timedelta(seconds=1),
'minute': datetime.timedelta(minutes=1),
'minutes': datetime.timedelta(minutes=1),
'hour': datetime.timedelta(hours=1),
'hours': datetime.timedelta(hours=1),
'day': datetime.timedelta(days=1),
'days': datetime.timedelta(days=1),
'week': datetime.timedelta(days=7),
'weeks': datetime.timedelta(days=7),
'month': datetime.timedelta(days=30),
'months': datetime.timedelta(days=30),
'year': datetime.timedelta(days=365),
'years': datetime.timedelta(days=365),
}
FORMAT_DATE_HEADER = '%a, %d %b %Y %H:%M:%S GMT'
def parse_duration(text: str) -> datetime.timedelta:
(num_str, unit_str) = text.split(' ')
num = float(num_str)
unit = DATETIME_UNITS[unit_str]
return unit * num
def parse_response_datetime(response) -> datetime.datetime:
return datetime.datetime.strptime(
response.headers['Date'],
FORMAT_DATE_HEADER,
).replace(tzinfo=datetime.UTC)
NOW = datetime.datetime.now(datetime.UTC)
LOCAL_TIMEZONE = NOW.astimezone().tzinfo
def try_parse(text: str, fmt: str) -> datetime.datetime | None:
try:
time = datetime.datetime.strptime(text, fmt) # noqa: DTZ007
if time.tzinfo is None:
time = time.replace(tzinfo=LOCAL_TIMEZONE)
except ValueError:
time = None
return time
def parse_time(text: str) -> datetime.datetime:
text = text.replace('\n', ' ')
text = text.strip()
time = try_parse(text, '%d %b %Y %I:%M:%S %p')
time = time or try_parse(text, '%d %b, %Y @ %I:%M%p')
if time is None and (m := try_parse(text, '%d %b @ %I:%M%p')):
time = m.replace(year=NOW.year)
if time is None:
msg = 'Unknown format: ' + text
raise RuntimeError(msg)
if time.tzinfo is None:
time = time.replace(tzinfo=LOCAL_TIMEZONE)
if time.tzinfo is None:
msg = 'Could not parse timezone: ' + text
raise RuntimeError(msg)
return time.astimezone(datetime.UTC)
def parse_date(text: str) -> datetime.date:
text = text.strip()
if dt := try_parse(text, '%d %B %Y'):
return dt.date()
if dt := try_parse(text, '%b %d, %Y'):
return dt.date()
if dt := try_parse(text, '%B %d, %Y'):
return dt.date()
if dt := try_parse(text, '%b %d'):
return dt.date()
msg = 'Unknown format: ' + text
raise RuntimeError(msg)