import datetime as dt
import pytz
import re
def parse_local_date(date_str: str) -> dt.datetime:
"""Parses common date string formats to local datetime objects."""
if isinstance(date_str, dt.datetime):
return date_str
date_formats = ['%Y-%m-%d %H:%M:%S.%f', '%Y-%m-%d %H:%M:%S', '%Y-%m-%d']
date = None
for date_format in date_formats:
try:
date = dt.datetime.strptime(date_str, date_format)
except ValueError:
pass
if date is None:
raise ValueError(f"Can't parse date: {date_str}")
return date
def parse_utc_date_with_limit(date_str: str, max_window_in_days: int = None) -> dt.datetime:
"""Parses common date string formats to UTC datetime objects."""
date = parse_local_date(date_str)
date_utc = date.astimezone(pytz.utc)
if max_window_in_days is not None:
now_utc = dt.datetime.utcnow().replace(tzinfo=pytz.utc)
max_window_date = now_utc - dt.timedelta(days=max_window_in_days)
if date_utc < max_window_date:
return max_window_date
return date_utc
def parse_utc_date(date_str: str) -> dt.datetime:
"""Parses common date string formats to UTC datetime objects."""
date = parse_local_date(date_str)
return date.astimezone(pytz.utc)
def utc_date_str_to_timestamp_ms(date_str: str) -> int:
"""Parses common date string formats into ms since the Unix epoch in UTC."""
date = parse_local_date(date_str)
date = date.replace(tzinfo=pytz.UTC)
return int(date.timestamp() * 1000)
def interval_str_to_duration_ms(interval_str: str) -> int:
"""Parses interval strings into how long they represent in ms.
Supported intervals:
- seconds (e.g. 1s)
- minutes (e.g. 5m)
- hours (e.g. 1h)
- days (e.g. 5d)
- weeks (e.g. 1w)
"""
duration_match = re.search(r'^\d+', interval_str)
time_unit_match = re.search('[smhdw]', interval_str)
if not duration_match or not time_unit_match:
raise ValueError('Invalid interval {}'.format(interval_str))
duration = int(duration_match.group())
time_unit = time_unit_match.group()
if time_unit == 's':
return duration * 1000
if time_unit == 'm':
return duration * 1000 * 60
if time_unit == 'h':
return duration * 1000 * 60 * 60
if time_unit == 'd':
return duration * 1000 * 60 * 60 * 24
if time_unit == 'w':
return duration * 1000 * 60 * 60 * 24 * 7