time conversion

This commit is contained in:
Daniel Tsvetkov 2021-08-18 15:53:40 +03:00
parent 9f1790c201
commit cd3a9e8943
3 changed files with 32 additions and 1 deletions

View File

@ -35,6 +35,9 @@ python tww QUERY [--debug] [--full] [--show=<param>]
- `05:23 - 150 minutes`
- `3 days from next Friday`
- `2 hours before 15:00`
- Time conversion: `* (years|months|weeks|days|hours|minutes|seconds) to (years|months|weeks|days|hours|minutes|seconds)`
- `108 hours to minutes`
- `314 minutes` (implicit conversion to automatic human-friendly output)
- (Approximate) workdays calculation (assumes monday-friday are work days - ignores public/local holidays (for now)): `work days/hours since/until <datetime-like>` or `
- `workdays since 2021-01-05`
- `work hours until Friday`

View File

@ -845,6 +845,8 @@ def td_totals(td):
years, months, weeks, days, hours, minutes, seconds = map(abs,
(years, months, weeks, days, hours, minutes, seconds))
return dict(
milliseconds=seconds*1e3,
microseconds=seconds*1e6,
seconds=seconds,
minutes=minutes,
hours=hours,

View File

@ -30,6 +30,8 @@ r_time_in = re.compile('(?:time)?\s*in\s*(.*)', flags=re.IGNORECASE)
r_time_since = re.compile('(?:time|year|month|week|day|hour|minute|second)?(?:s)?\s*(?:since|ago)\s*(.*)', flags=re.IGNORECASE)
r_time_until = re.compile('(?:time|year|month|week|day|hour|minute|second)?(?:s)?\s*(?:until|to)\s*(.*)', flags=re.IGNORECASE)
r_time_between = re.compile('(?:time|year|month|week|day|hour|minute|second)?(?:s)?\s*between\s*(.*)\s*and\s*(.*)', flags=re.IGNORECASE)
r_time_conversion = re.compile('\s*(.*)\s*(year|month|week|day|hour|minute|second|microsecond|millisecond)(?:s)?', flags=re.IGNORECASE)
r_time_conversion_to = re.compile('\s*(.*)\s*(year|month|week|day|hour|minute|second|microsecond|millisecond)(?:s)?\s*to\s*(year|month|week|day|hour|minute|second|microsecond|millisecond)(?:s)', flags=re.IGNORECASE)
r_tz_between = re.compile('(?:time difference|tz diff|time diff|time zone difference|timezone difference|timezone diff|time zone diff)?(?:s)?\s*between\s*(.*)\s*and\s*(.*)', flags=re.IGNORECASE)
r_time_plus = re.compile('(.*)\s*(?:plus|\+|after|from)\s*(.*)', flags=re.IGNORECASE)
r_time_minus = re.compile('(.*)\s*(?:minus|\-)\s*(.*)', flags=re.IGNORECASE)
@ -88,6 +90,24 @@ def handler_time_diff(start_dt, end_dt) -> dict:
diff=td_pretty(diff))
def handler_time_conversion(time_d, input_f, output_f=None) -> dict:
time_d = int(time_d)
if input_f in ['year']:
td = timedelta(days=365*time_d)
elif input_f in ['month']:
td = timedelta(days=30*time_d)
elif input_f in ['week', 'day', 'hour', 'minute', 'second', 'microsecond', 'millisecond']:
td = timedelta(**{"{}s".format(input_f): time_d})
else:
td = timedelta()
td_p = td_pretty(td)
if not output_f:
out = td_p['duration_human']
else:
out = "{} {}s".format(td_p['totals']["{}s".format(output_f)], output_f)
return dict(out=out, timedelta=td_p)
def handler_time_since_until(start_dt_s: str) -> dict:
return handler_time_diff(start_dt_s, get_local_now())
@ -210,6 +230,7 @@ QUERY_TYPE_DT_TR = "datetime_translation"
QUERY_TYPE_DT = "datetime_details"
QUERY_TYPE_TZ = "timezone"
QUERY_TYPE_TD = "timedelta"
QUERY_TYPE_CONV = "conversion"
QUERY_TYPE_CAL = "calendar"
h_default = ''
@ -223,11 +244,14 @@ h_time_in = 'dt->hh:mm'
h_translation = 'dt->iso8601_full'
h_default_dt = 'dt->iso8601_full'
h_default_td = 'timedelta->diff->duration_human'
h_default_conv = 'conv->out'
h_day_of_week = 'dt->locale_day_of_week'
h_cal_year = 'cal->year'
h_cal_month = 'cal->month'
regex_handlers = [
(r_time_conversion_to, handler_time_conversion, QUERY_TYPE_CONV, [h_default_conv]),
(r_time_conversion, handler_time_conversion, QUERY_TYPE_CONV, [h_default_conv]),
(r_time_in_epoch_s_now, handler_time_now_local, QUERY_TYPE_DT, [h_unix_s]),
(r_time_in_epoch_s_now, handler_time_now_utc, QUERY_TYPE_DT, [h_unix_s]),
(r_time_in_epoch_s2, handler_generic_parser, QUERY_TYPE_DT, [h_unix_s]),
@ -391,7 +415,7 @@ def resolve_query(query, allowed_queries=None):
}
solutions = resolve_query_type(query)
if not allowed_queries:
allowed_queries = [QUERY_TYPE_DT, QUERY_TYPE_DT_TR, QUERY_TYPE_TD, QUERY_TYPE_TZ, QUERY_TYPE_CAL]
allowed_queries = [QUERY_TYPE_DT, QUERY_TYPE_DT_TR, QUERY_TYPE_TD, QUERY_TYPE_TZ, QUERY_TYPE_CAL, QUERY_TYPE_CONV]
for sol_id, solution in enumerate(solutions):
element = {}
handler, results, query_type, hi = solution
@ -414,6 +438,8 @@ def resolve_query(query, allowed_queries=None):
element["timedelta"] = results
elif query_type == QUERY_TYPE_CAL:
element["cal"] = results
elif query_type == QUERY_TYPE_CONV:
element["conv"] = results
rv["solutions"].append(element)
except Exception as e:
continue