Last active
May 8, 2023 04:02
Python time duration as in golang
This file contains hidden or 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 re | |
import time | |
from datetime import datetime, timedelta | |
class DurationUnits: | |
Nanosecond = 1 | |
Microsecond = 1000 * Nanosecond | |
Millisecond = 1000 * Microsecond | |
Second = 1000 * Millisecond | |
Minute = 60 * Second | |
Hour = 60 * Minute | |
class Duration: | |
unitMap = dict( | |
ns=DurationUnits.Nanosecond, | |
us=DurationUnits.Microsecond, | |
# µs=DurationUnits.Microsecond, # U+00B5 = micro symbol | |
# μs=1000000, # U+03BC = Greek letter mu | |
ms=DurationUnits.Millisecond, | |
s=DurationUnits.Second, | |
m=DurationUnits.Minute, | |
h=DurationUnits.Hour, | |
) | |
@classmethod | |
def parse_duration(cls, s: str): | |
n = int(0) | |
sign = '+' | |
if s[0] == '+' or s[0] == '-': | |
sign, s = s[0], s[1:] | |
while len(s): | |
m = re.match(r"([0-9]+(\.[0-9]+)?)([^0-9]+)", s) | |
unit = cls.unitMap.get(m.groups()[2], None) | |
if unit is None: | |
raise Exception("Missing unit: " + s) | |
n += int(unit * float(m.groups()[0])) | |
s = s[len(m.groups()[0]) + len(m.groups()[2]):] | |
if sign == '-': | |
n *= -1 | |
return cls(n) | |
def __str__(self): | |
spec = [] | |
n, neg = abs(self.n), self.n < 0 | |
for u in reversed([u for u in self.unitMap]): | |
m = n // self.unitMap[u] | |
if m > 0: | |
spec.append(str(m) + str(u)) | |
n -= int(self.unitMap[u] * (n // self.unitMap[u])) | |
if neg: | |
return '-' + ''.join(spec) | |
return '+' + ''.join(spec) | |
def __init__(self, n: int): | |
self.n = n | |
@property | |
def nanoseconds(self): | |
return int(self.n) | |
@property | |
def microseconds(self): | |
return int(self.n / self.unitMap['us']) | |
@property | |
def milliseconds(self): | |
return int(self.n / self.unitMap['ms']) | |
@property | |
def seconds(self): | |
return int(self.n / self.unitMap['s']) | |
@property | |
def minutes(self): | |
return int(self.n / self.unitMap['m']) | |
@property | |
def hours(self): | |
return int(self.n / self.unitMap['h']) | |
def sleep(self): | |
time.sleep(int(self.n / self.unitMap['s'])) | |
def timedelta(self) -> timedelta: | |
return timedelta(microseconds=self.microseconds) | |
def add(self, dt: datetime) -> datetime: | |
return dt + self.timedelta() | |
def sub(self, dt: datetime) -> datetime: | |
return dt - self.timedelta() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment