timedelta formatter
This commit is contained in:
parent
abbba47bb5
commit
ddd352865a
@ -1,12 +1,13 @@
|
|||||||
import json
|
import json
|
||||||
import re
|
import re
|
||||||
|
import sys
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
from pygments import highlight, lexers, formatters
|
from pygments import highlight, lexers, formatters
|
||||||
|
|
||||||
from tww import ISO_FORMAT, time_to_emoji
|
from tww import ISO_FORMAT, time_to_emoji, time_ago
|
||||||
from tww import resolve_timezone, dateparser_parse_dt, get_utcnow, get_s_since_epoch, get_ms_since_epoch, \
|
from tww import resolve_timezone, dateparser_parse_dt, get_utcnow, get_s_since_epoch, get_ms_since_epoch, \
|
||||||
dt_tz_translation, DEFAULT_FORMAT, get_local_now, query_to_format_result
|
dt_tz_translation, get_local_now, query_to_format_result
|
||||||
|
|
||||||
r_generic = re.compile('(.*)', flags=re.IGNORECASE)
|
r_generic = re.compile('(.*)', flags=re.IGNORECASE)
|
||||||
r_time_in_epoch_s_now = re.compile('(?:time since epoch|seconds since epoch)', flags=re.IGNORECASE)
|
r_time_in_epoch_s_now = re.compile('(?:time since epoch|seconds since epoch)', flags=re.IGNORECASE)
|
||||||
@ -48,34 +49,30 @@ def handler_time_ms_now_utc() -> int:
|
|||||||
return get_ms_since_epoch(get_utcnow())
|
return get_ms_since_epoch(get_utcnow())
|
||||||
|
|
||||||
|
|
||||||
def handler_time_diff(start_dt: str, end_dt: str) -> dict:
|
def handler_time_diff(start_dt: datetime, end_dt: datetime) -> dict:
|
||||||
start, end = dateparser_parse_dt(start_dt), dateparser_parse_dt(end_dt)
|
diff = end_dt - start_dt
|
||||||
return dict(start=start.strftime(DEFAULT_FORMAT),
|
return dict(start=dt_pretty(start_dt),
|
||||||
end=end.strftime(DEFAULT_FORMAT),
|
end=dt_pretty(end_dt),
|
||||||
diff=end - start)
|
diff=td_pretty(diff))
|
||||||
|
|
||||||
|
|
||||||
def handler_time_since(start_dt_s: str) -> dict:
|
def handler_time_since_until(start_dt_s: str) -> dict:
|
||||||
return handler_time_diff(start_dt_s, str(get_utcnow()))
|
return handler_time_diff(dateparser_parse_dt(start_dt_s), get_local_now())
|
||||||
|
|
||||||
|
|
||||||
def handler_time_until(end_dt_s: str) -> dict:
|
|
||||||
return handler_time_diff(str(get_utcnow()), end_dt_s)
|
|
||||||
|
|
||||||
|
|
||||||
def handler_timezone_translation(dt_s: str, timezone_like_s: str) -> dict:
|
def handler_timezone_translation(dt_s: str, timezone_like_s: str) -> dict:
|
||||||
dt = dateparser_parse_dt(dt_s)
|
src_dt = dateparser_parse_dt(dt_s)
|
||||||
tz = resolve_timezone(timezone_like_s)
|
tz = resolve_timezone(timezone_like_s)
|
||||||
if not tz:
|
if not tz:
|
||||||
tz, offset, the_time = '', '', dt
|
tz, dst_dt = {}, src_dt
|
||||||
else:
|
else:
|
||||||
offset = tz.get('tz_offset')
|
offset = tz.get('tz_offset')
|
||||||
translation = dt_tz_translation(dt, offset)
|
dst_dt = dt_tz_translation(src_dt, offset)
|
||||||
the_time = translation.strftime(DEFAULT_FORMAT)
|
return dict(
|
||||||
return dict(dt=the_time,
|
src_dt=dt_pretty(src_dt),
|
||||||
offset=offset,
|
dst_dt=dt_pretty(dst_dt),
|
||||||
tz=tz,
|
tz=tz,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def handler_generic_parser(dt_s: str) -> datetime:
|
def handler_generic_parser(dt_s: str) -> datetime:
|
||||||
@ -109,8 +106,8 @@ regex_handlers = [
|
|||||||
(r_time_in_epoch_ms2, handler_time_ms, QUERY_TYPE_DT),
|
(r_time_in_epoch_ms2, handler_time_ms, QUERY_TYPE_DT),
|
||||||
(r_time_in_epoch_ms3, handler_time_ms, QUERY_TYPE_DT),
|
(r_time_in_epoch_ms3, handler_time_ms, QUERY_TYPE_DT),
|
||||||
(r_timezone_translation, handler_timezone_translation, QUERY_TYPE_DT_TR),
|
(r_timezone_translation, handler_timezone_translation, QUERY_TYPE_DT_TR),
|
||||||
(r_time_since, handler_time_since, QUERY_TYPE_TD),
|
(r_time_since, handler_time_since_until, QUERY_TYPE_TD),
|
||||||
(r_time_until, handler_time_until, QUERY_TYPE_TD),
|
(r_time_until, handler_time_since_until, QUERY_TYPE_TD),
|
||||||
(r_time_between, handler_time_diff, QUERY_TYPE_TD),
|
(r_time_between, handler_time_diff, QUERY_TYPE_TD),
|
||||||
(r_time_in, handler_time_in_parser, QUERY_TYPE_DT),
|
(r_time_in, handler_time_in_parser, QUERY_TYPE_DT),
|
||||||
(r_timezone, handler_timezone, QUERY_TYPE_TZ),
|
(r_timezone, handler_timezone, QUERY_TYPE_TZ),
|
||||||
@ -140,7 +137,7 @@ def tokenize(s):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
continue
|
continue
|
||||||
if result is not None:
|
if result is not None:
|
||||||
solutions.append((h.__name__, (result, ), t))
|
solutions.append((h.__name__, (result,), t))
|
||||||
return solutions
|
return solutions
|
||||||
|
|
||||||
|
|
||||||
@ -197,6 +194,74 @@ def dt_pretty(dt):
|
|||||||
return rv
|
return rv
|
||||||
|
|
||||||
|
|
||||||
|
def td_remainders(td):
|
||||||
|
# split seconds to larger units
|
||||||
|
seconds = td.total_seconds()
|
||||||
|
minutes, seconds = divmod(seconds, 60)
|
||||||
|
hours, minutes = divmod(minutes, 60)
|
||||||
|
days, hours = divmod(hours, 24)
|
||||||
|
months, days = divmod(days, 30.42)
|
||||||
|
years, months = divmod(months, 12)
|
||||||
|
years, months, days, hours, minutes, seconds = map(int, (years, months, days, hours, minutes, seconds))
|
||||||
|
years, months, days, hours, minutes, seconds = map(abs, (years, months, days, hours, minutes, seconds))
|
||||||
|
return dict(
|
||||||
|
seconds=seconds,
|
||||||
|
minutes=minutes,
|
||||||
|
hours=hours,
|
||||||
|
days=days,
|
||||||
|
months=months,
|
||||||
|
years=years,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def td_totals(td):
|
||||||
|
seconds = td.total_seconds()
|
||||||
|
minutes = seconds // 60
|
||||||
|
hours = seconds // (60 * 60)
|
||||||
|
days = seconds // (24 * 60 * 60)
|
||||||
|
weeks = seconds // (7 * 24 * 60 * 60)
|
||||||
|
months = seconds // (30 * 24 * 60 * 60)
|
||||||
|
years = seconds // (365 * 24 * 60 * 60)
|
||||||
|
years, months, weeks, days, hours, minutes, seconds = map(abs, (years, months, weeks, days, hours, minutes, seconds))
|
||||||
|
return dict(
|
||||||
|
seconds=seconds,
|
||||||
|
minutes=minutes,
|
||||||
|
hours=hours,
|
||||||
|
days=days,
|
||||||
|
weeks=weeks,
|
||||||
|
months=months,
|
||||||
|
years=years,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def td_iso8601(td):
|
||||||
|
"""P[n]Y[n]M[n]DT[n]H[n]M[n]S"""
|
||||||
|
rem = td_remainders(td)
|
||||||
|
fmt = "P"
|
||||||
|
for short, timeframe in [("Y", "years"), ("M", "months"), ("D", "days")]:
|
||||||
|
if rem[timeframe]:
|
||||||
|
fmt += "{}{}".format(rem[timeframe], short)
|
||||||
|
hms = [("H", "hours"), ("M", "minutes"), ("S", "seconds")]
|
||||||
|
if any([rem[t[1]] for t in hms]):
|
||||||
|
fmt += "T"
|
||||||
|
for short, timeframe in hms:
|
||||||
|
if rem[timeframe]:
|
||||||
|
fmt += "{}{}".format(rem[timeframe], short)
|
||||||
|
return fmt
|
||||||
|
|
||||||
|
|
||||||
|
def td_pretty(td):
|
||||||
|
rv = {
|
||||||
|
"sign": '-' if td.days < 0 else '+',
|
||||||
|
"in_the": 'future' if td.days < 0 else 'past',
|
||||||
|
"time_ago": time_ago(td),
|
||||||
|
"duration_iso8601": td_iso8601(td),
|
||||||
|
"totals": td_totals(td),
|
||||||
|
"remainders": td_remainders(td),
|
||||||
|
}
|
||||||
|
return rv
|
||||||
|
|
||||||
|
|
||||||
def resolve_query_type(query):
|
def resolve_query_type(query):
|
||||||
solutions = tokenize(query)
|
solutions = tokenize(query)
|
||||||
if not solutions:
|
if not solutions:
|
||||||
@ -230,7 +295,7 @@ def resolve_query(query):
|
|||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
query = "now in sofia"
|
# query = "time since 27 January 1992"
|
||||||
# query = ' '.join(sys.argv[1:])
|
query = ' '.join(sys.argv[1:])
|
||||||
result = resolve_query(query)
|
result = resolve_query(query)
|
||||||
pretty_print_dict(result)
|
pretty_print_dict(result)
|
||||||
|
Loading…
Reference in New Issue
Block a user