For a project I'm working on we need a basic time holder class. This is written in CircuitPython, which is a stripped down version of CPython that's missing a number of libraries, including the whole datetime library.
The class definition is as follows. Note that TimeDelta
is very similar, it also holds a second and day count, but is meant to represent a duration rather than a single point in time. Thus a different class for the different semantic meaning.
__hms_to_secs()
and __ymd_to_days()
do exactly what their names suggest they ought to.
class TimeStamp: def __init__(self, year = 2000, month = 1, day = 1, hours = 0, minutes = 0, seconds = 0): self.seconds = __hms_to_secs(hours, minutes, seconds) self.days = __ymd_to_days(year, month, day) self.normalize() def normalize(self): if self.seconds < 0 or self.seconds >= 86400: day_error = self.seconds // 86400 self.seconds -= day_error * 86400 self.days += day_error return self def __add__(self, rhs) return (TimeStamp(self.days + rhs.days, 0, 0, self.seconds + rhs.seconds) if isinstance(rhs, TimeDelta) else TimeDelta(self.days, 0, 0, self.seconds + rhs)).normalize() def __sub__(self, rhs) return (TimeDelta(self.days - rhs.days, 0, 0, self.seconds - rhs.seconds) if isinstance(rhs, TimeDelta) else TimeDelta(self.days, 0, 0, self.seconds - rhs)).normalize()
The one thing I'm curious about is the normalize()
method. By both modifying self
and returning it as well, it allows both
time_stamp.normalize()
and
return temporary_time_stamp.normalize()
to work like you'd expect. But as a relative newcomer to Python I have no idea if this is considered good style. Also observations on __add__()
and __sub__()
are welcome. Is there a preference for longer "do it all" statements, or for breaking them up into two or more bite sized lines? The intention is to offer two overloads, either adding a TimeDelta
or a raw count of seconds.
As a 40 year career C/C++ programmer, overloading based on parameter type is second nature to me. I miss it a lot in Python, which can't do it due to the fact it's duck-typed. So I've taken to doing the overload resolution at run-time.