timedelta formatter
This commit is contained in:
parent
abbba47bb5
commit
ddd352865a
@ -1,12 +1,13 @@
|
||||
import json
|
||||
import re
|
||||
import sys
|
||||
from datetime import datetime
|
||||
|
||||
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, \
|
||||
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_time_in_epoch_s_now = re.compile('(?:time since epoch|seconds since epoch)', flags=re.IGNORECASE)
|
||||
@ -48,32 +49,28 @@ def handler_time_ms_now_utc() -> int:
|
||||
return get_ms_since_epoch(get_utcnow())
|
||||
|
||||
|
||||
def handler_time_diff(start_dt: str, end_dt: str) -> dict:
|
||||
start, end = dateparser_parse_dt(start_dt), dateparser_parse_dt(end_dt)
|
||||
return dict(start=start.strftime(DEFAULT_FORMAT),
|
||||
end=end.strftime(DEFAULT_FORMAT),
|
||||
diff=end - start)
|
||||
def handler_time_diff(start_dt: datetime, end_dt: datetime) -> dict:
|
||||
diff = end_dt - start_dt
|
||||
return dict(start=dt_pretty(start_dt),
|
||||
end=dt_pretty(end_dt),
|
||||
diff=td_pretty(diff))
|
||||
|
||||
|
||||
def handler_time_since(start_dt_s: str) -> dict:
|
||||
return handler_time_diff(start_dt_s, str(get_utcnow()))
|
||||
|
||||
|
||||
def handler_time_until(end_dt_s: str) -> dict:
|
||||
return handler_time_diff(str(get_utcnow()), end_dt_s)
|
||||
def handler_time_since_until(start_dt_s: str) -> dict:
|
||||
return handler_time_diff(dateparser_parse_dt(start_dt_s), get_local_now())
|
||||
|
||||
|
||||
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)
|
||||
if not tz:
|
||||
tz, offset, the_time = '', '', dt
|
||||
tz, dst_dt = {}, src_dt
|
||||
else:
|
||||
offset = tz.get('tz_offset')
|
||||
translation = dt_tz_translation(dt, offset)
|
||||
the_time = translation.strftime(DEFAULT_FORMAT)
|
||||
return dict(dt=the_time,
|
||||
offset=offset,
|
||||
dst_dt = dt_tz_translation(src_dt, offset)
|
||||
return dict(
|
||||
src_dt=dt_pretty(src_dt),
|
||||
dst_dt=dt_pretty(dst_dt),
|
||||
tz=tz,
|
||||
)
|
||||
|
||||
@ -109,8 +106,8 @@ regex_handlers = [
|
||||
(r_time_in_epoch_ms2, 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_time_since, handler_time_since, QUERY_TYPE_TD),
|
||||
(r_time_until, handler_time_until, QUERY_TYPE_TD),
|
||||
(r_time_since, handler_time_since_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_in, handler_time_in_parser, QUERY_TYPE_DT),
|
||||
(r_timezone, handler_timezone, QUERY_TYPE_TZ),
|
||||
@ -140,7 +137,7 @@ def tokenize(s):
|
||||
except Exception as e:
|
||||
continue
|
||||
if result is not None:
|
||||
solutions.append((h.__name__, (result, ), t))
|
||||
solutions.append((h.__name__, (result,), t))
|
||||
return solutions
|
||||
|
||||
|
||||
@ -197,6 +194,74 @@ def dt_pretty(dt):
|
||||
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):
|
||||
solutions = tokenize(query)
|
||||
if not solutions:
|
||||
@ -230,7 +295,7 @@ def resolve_query(query):
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
query = "now in sofia"
|
||||
# query = ' '.join(sys.argv[1:])
|
||||
# query = "time since 27 January 1992"
|
||||
query = ' '.join(sys.argv[1:])
|
||||
result = resolve_query(query)
|
||||
pretty_print_dict(result)
|
||||
|
Loading…
Reference in New Issue
Block a user