tenfourfox/testing/taskcluster/taskcluster_graph/from_now.py
Cameron Kaiser c9b2922b70 hello FPR
2017-04-19 00:56:45 -07:00

86 lines
2.4 KiB
Python

# Python port of the ms.js node module this is not a direct port some things are
# more complicated or less precise and we lean on time delta here.
import re
import datetime
PATTERN=re.compile(
'((?:\d+)?\.?\d+) *([a-z])'
)
def seconds(value):
return datetime.timedelta(seconds=int(value))
def minutes(value):
return datetime.timedelta(minutes=int(value))
def hours(value):
return datetime.timedelta(hours=int(value))
def days (value):
return datetime.timedelta(days=int(value))
def years(value):
# Warning here "years" are vague don't use this for really sensitive date
# computation the idea is to give you a absolute amount of time in the
# future which is not the same thing as "precisely on this date next year"
return datetime.timedelta(days=int(value) * 365)
ALIASES = {}
ALIASES['seconds'] = ALIASES['second'] = ALIASES['s'] = seconds
ALIASES['minutes'] = ALIASES['minute'] = ALIASES['m'] = minutes
ALIASES['hours'] = ALIASES['hour'] = ALIASES['h'] = hours
ALIASES['days'] = ALIASES['day'] = ALIASES['d'] = days
ALIASES['years'] = ALIASES['year'] = ALIASES['y'] = years
class InvalidString(Exception):
pass
class UnknownTimeMeasurement(Exception):
pass
def value_of(input_str):
'''
Convert a string to a json date in the future
:param str input_str: (ex: 1d, 2d, 6years, 2 seconds)
:returns: Unit given in seconds
'''
matches = PATTERN.search(input_str)
if matches is None or len(matches.groups()) < 2:
raise InvalidString("'{}' is invalid string".format(input_str))
value, unit = matches.groups()
if unit not in ALIASES:
raise UnknownTimeMeasurement(
'{} is not a valid time measure use one of {}'.format(unit,
sorted(ALIASES.keys()))
)
return ALIASES[unit](value)
def json_time_from_now(input_str, now=None):
'''
:param str input_str: Input string (see value of)
:param datetime now: Optionally set the definition of `now`
:returns: JSON string representation of time in future.
'''
if now is None:
now = datetime.datetime.utcnow()
time = now + value_of(input_str)
# Sorta a big hack but the json schema validator for date does not like the
# ISO dates until 'Z' (for timezone) is added...
return time.isoformat() + 'Z'
def current_json_time():
'''
:returns: JSON string representation of the current time.
'''
return datetime.datetime.utcnow().isoformat() + 'Z'