Last active
May 8, 2023 04:02
-
-
Save dberstein/8c3ff37b04958b6f875e018b92fccf3f to your computer and use it in GitHub Desktop.
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