import datetime import functools import time def timer(func): """Print the runtime of the decorated function""" @functools.wraps(func) def wrapper_timer(*args, **kwargs): start_time = time.perf_counter() # 1 value = func(*args, **kwargs) end_time = time.perf_counter() # 2 run_time = end_time - start_time # 3 print(f"Finished {func.__name__!r} in {run_time:.4f} secs") return value return wrapper_timer def humanize_date_difference( older: datetime, newer: datetime = None, offset: int = None, debug=False ): if newer: dt = newer - older milliseconds = dt.microseconds / 1e3 offset = milliseconds + (dt.seconds * 1000) + (dt.days * 1000 * 60 * 60 * 24) if offset: if debug: print(f"{offset} s offset") delta_ms = int(offset % 1000) offset /= 1e3 delta_s = int(offset % 60) offset /= 60 delta_m = int(offset % 60) offset /= 60 delta_h = int(offset % 24) offset /= 24 delta_d = int(offset) if debug: print("{:d} ms".format(delta_ms)) print("{:d} s".format(delta_s)) print("{:d} m".format(delta_m)) print("{:d} h".format(delta_h)) print("{:d} d".format(delta_d)) else: raise ValueError("Must supply otherdate or offset (from now)") if delta_d > 1: if delta_d > 6: date = older + datetime.timedelta( days=-delta_d, hours=-delta_h, minutes=-delta_m ) return date.strftime("%A, %Y %B %m, %H:%I") else: wday = older + datetime.timedelta(days=-delta_d) return wday.strftime("%A") if delta_d == 1: return "Yesterday" if delta_h > 0: return "{:.0f}h {:.0f}m ago".format(delta_h, delta_m) if delta_m > 0: return "{:.0f}m {:.0f}s ago".format(delta_m, delta_s) if delta_s > 0: return "{:.0f}s ago".format(delta_s) else: return "{:.0f} ms ago".format(delta_ms) if __name__ == "__main__": date1 = datetime.datetime.now() date2 = datetime.datetime.now() - datetime.timedelta(milliseconds=20) print(humanize_date_difference(date2, date1, debug=True))