Skip to content

Instantly share code, notes, and snippets.

@dnicolodi
Created January 15, 2021 18:20
Show Gist options
  • Save dnicolodi/ed1d5f983cbb413da49c85e745c111f2 to your computer and use it in GitHub Desktop.
Save dnicolodi/ed1d5f983cbb413da49c85e745c111f2 to your computer and use it in GitHub Desktop.
class Duration(timedelta):
def __new__(cls, value):
if isinstance(value, timedelta):
return cls(value.total_seconds())
return super(Duration, cls).__new__(cls, seconds=value)
@classmethod
def parse(cls, s):
sign = 1
if s[0] == '-':
sign = -1
s = s[1:]
hours, minutes = map(int, s.split('.'))
seconds = sign * (abs(hours) * 3600 + abs(minutes) * 60)
return cls(seconds)
def __repr__(self):
return '{:s}({:f})'.format(self.__class__.__name__, self.total_seconds())
def __str__(self):
return format(self)
def __format__(self, frmt=None):
if not frmt:
frmt = '%z%Hh%M'
value = self.total_seconds()
sign = '-' if value < 0 else '+'
seconds = int(abs(value))
hours, seconds = divmod(seconds, 3600)
minutes, seconds = divmod(seconds, 60)
table = {'z': ('sign', '1s'),
'H': ('hours', '02d'),
'M': ('minutes', '02d'),
'S': ('seconds', '02d'),
'T': ('value', 'f')}
def replace(m):
value, default = table[m.group(2)]
spec = m.group(1) or default
return f'{{{value:}:{spec:}}}'
return re.sub('%(\d*)(\w)', replace, frmt).format(**locals())
def __bool__(self):
return self.total_seconds() != 0
def __eq__(self, other):
return self.total_seconds() == other
def __lt__(self, other):
return self.total_seconds() < other
def __sub__(self, other):
return Duration(self.total_seconds() - other.total_seconds())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment