Skip to content

Instantly share code, notes, and snippets.

@dberstein
Last active May 8, 2023 04:02
Show Gist options
  • Save dberstein/8c3ff37b04958b6f875e018b92fccf3f to your computer and use it in GitHub Desktop.
Save dberstein/8c3ff37b04958b6f875e018b92fccf3f to your computer and use it in GitHub Desktop.
Python time duration as in golang
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