Created
October 25, 2019 20:06
-
-
Save thorwhalen/82603b6df28bc842741b421668d2a83f to your computer and use it in GitHub Desktop.
A util to get a number of seconds from a (flexible) string description of a duration using day, hour, minutes, and seconds units.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import time | |
import re | |
p = re.compile('[\d\.]+') | |
seconds_for_unit = { | |
'd': 60 * 60 * 24, | |
'h': 60 * 60, | |
'm': 60, | |
's': 1 | |
} | |
def time_spec_to_seconds(time_spec: str) -> float: | |
"""A flexible way to get a time (duration) in seconds, from a string. | |
How flexible? Well, the string needs to interleave numbers and words, and the first letter of the word needs | |
to be d (day), h (hour), m (minute), or s (second). The function will ignore the rest. | |
Args: | |
time_spec: The string specifying the time | |
Returns: A duration, float, in seconds. | |
>>> assert time_spec_to_seconds('5 minutes') == 300.0 | |
>>> assert time_spec_to_seconds('1heure 1mn 1 secondi') == 3600 + 60 + 1 # only the first letter of the unit counts | |
>>> assert time_spec_to_seconds('72m109.7s') == 4429.7 # numbers don't have a limit and can use decimals | |
>>> assert time_spec_to_seconds('3h 12mn42 seconds') == 11562.0 | |
""" | |
requested_time = None | |
keys = list(map(str.strip, p.split(time_spec))) | |
vals = list(map(float, p.findall(time_spec))) | |
if keys[0] == '': | |
keys = keys[1:] | |
if len(keys) >= 1 and len(vals) >= 1: | |
duration_spec = list(zip(vals, keys)) | |
requested_time = 0 | |
for val, unit in duration_spec: | |
seconds_to_add = val * seconds_for_unit.get(unit[0], None) | |
if seconds_to_add is None: | |
raise ValueError( | |
f"Malformated time string (should use units d, h, m, and s): {time_spec}") | |
requested_time += seconds_to_add | |
return requested_time | |
def now_minus_spec_to_utc_seconds(now_minus_spec: str) -> float: | |
"""Get the UTC time of now minus some duration. | |
Input must start with a dash (that is, the minus symbol "-") and then describe a duration, | |
with days, hours, minutes, and/or seconds. | |
Args: | |
now_minus_spec: A string starting with "-" and then interleaving numbers and time units | |
Returns: A UTC seconds float | |
Examples: | |
now_minus_spec_to_utc_seconds('- 1 hour 2 mn 43s') | |
""" | |
assert now_minus_spec.startswith('-'), "String should start with '-'" | |
return time.time() - time_spec_to_seconds(now_minus_spec[1:]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment