def timedelta_encoder(delta: relativedelta): ndelta = delta.normalized() return ( ndelta.years * 12 + ndelta.months, ndelta.days, (ndelta.hours * 3600 + ndelta.minutes * 60 + ndelta.seconds) * 1_000_000 + ndelta.microseconds, )
def stringify_reldelta(rel_delta: relativedelta, min_unit: str = "seconds") -> str: """ Convert `dateutil.relativedelta.relativedelta` into a readable string `min_unit` is used to specify the printed precision, aviable precision levels are: * `years` * `months` * `weeks` * `days` * `hours` * `minutes` * `seconds` * `microseconds` These let you determine which unit will be the last one, for example with precision of `days` from: `1 year 2 months 2 weeks 5 days 4 hours 2 minutes and 1 second` you'd get: `1 year 2 months 2 weeks and 5 days` """ rel_delta = rel_delta.normalized() time_dict = { "years": rel_delta.years, "months": rel_delta.months, "weeks": rel_delta.weeks, "days": rel_delta.days, "hours": rel_delta.hours, "minutes": rel_delta.minutes, "seconds": rel_delta.seconds, "microseconds": rel_delta.microseconds, } stringified_time = "" time_list = [] for unit, value in time_dict.items(): if value: time_list.append( f"{int(value)} {unit if value != 1 else unit[:-1]}") if unit == min_unit: break if len(time_list) > 1: stringified_time = " ".join(time_list[:-1]) stringified_time += f" and {time_list[-1]}" elif len(time_list) == 0: stringified_time = "now" else: stringified_time = time_list[0] return stringified_time
def getRandomTime(start: datetime, end: datetime, step: relativedelta): if start == end: return start if relativedelta is None: if random.randint(0, 1) == 0: return start else: return end steps = (end.timestamp() - start.timestamp()) / step.total_seconds() steps = floor(steps) #make an integer (this should not change the value) radomdelta = relativedelta(seconds=step.total_seconds * random.randint(0, steps)) return end - radomdelta
def repr_rdelta(delta: relativedelta) -> str: delta = delta.normalized() msg = f"ca. {delta.weeks} weeks" return msg or "n.A."
def stringify_reldelta(rel_delta: relativedelta, min_unit: str = "seconds", max_units: int = 8) -> str: """ Convert `dateutil.relativedelta.relativedelta` into a readable string `min_unit` is used to specify the printed precision, aviable precision levels are: * `years` * `months` * `weeks` * `days` * `hours` * `minutes` * `seconds` * `microseconds` These let you determine which unit will be the last one, for example with precision of `days` from: `1 year 2 months 2 weeks 5 days 4 hours 2 minutes and 1 second` you'd get: `1 year 2 months 2 weeks and 5 days` `max_units` is the maximum amount of units to be used. If the produced string would go over this amount, smaller units will be cut to fit into this number. """ rel_delta = rel_delta.normalized() time_dict = { "years": rel_delta.years, "months": rel_delta.months, "weeks": rel_delta.weeks, "days": rel_delta.days, "hours": rel_delta.hours, "minutes": rel_delta.minutes, "seconds": rel_delta.seconds, "microseconds": rel_delta.microseconds, } stringified_time = "" time_list = [] for unit, value in time_dict.items(): # Stop early and don't parse smaller units # if we already hit the max allowed amount of units if len(time_list) == max_units: break if value: time_list.append( f"{int(value)} {unit if value != 1 else unit[:-1]}") # Stop if we hit the minimal unit if unit == min_unit: break if len(time_list) > 1: stringified_time = " ".join(time_list[:-1]) stringified_time += f" and {time_list[-1]}" elif len(time_list) == 0: stringified_time = "now" else: stringified_time = time_list[0] return stringified_time
def relativedelta_str(rd: relativedelta, **kwargs): rd = rd.normalized() s = relativedelta_total_seconds(rd) return seconds_str(s, **kwargs)