I'm writing a small clock object in Python that can be started, stopped and reset. I'm having difficulty knowing how to keep track of the accumulation of time correctly. Right now, the way the update procedure is written, the clock accumulates too much time (because of calls to the update method). I'm not sure how to write this such that it accumulates the correct time.
import time
import datetime
class Clock(object):
def __init__(
self,
name = None,
start = True
):
self._name = name
self._start = start # Boolean start clock on instantiation
# If a global clock list is detected, add a clock instance to it.
if "clocks" in globals():
clocks.add(self)
self.reset()
if self._start:
self.start()
def start(self):
self._startTime = datetime.datetime.utcnow()
def stop(self):
self._startTime = None
# Update the clock accumulator.
def update(self):
self.accumulator += (
datetime.datetime.utcnow() - self._startTime
)
def reset(self):
self.accumulator = datetime.timedelta(0)
self._startTime = None
# If the clock has a start time, add the difference between now and the
# start time to the accumulator and return the accumulation. If the clock
# does not have a start time, return the accumulation.
def elapsed(self):
if self._startTime:
self.update()
return(self.accumulator)
def time(self):
return(self.elapsed().total_seconds())
clock = Clock()
print clock.time()
print "starting"; clock.start()
for i in range(4):
time.sleep(3)
print clock.time()
print "stopping"; clock.stop()
for i in range(4):
time.sleep(3)
print clock.time()
print "starting"; clock.start()
for i in range(4):
time.sleep(3)
print clock.time()
print "resetting"; clock.reset()
print clock.time()
If you just add a call to
self.start()
at the end ofupdate
then I think it will work the way you are intending.The reason you are seeing the issue with the current code is you are adding the total offset from
_startTime
tonow()
each time you update, but you only want the difference betweennow()
and when the timer started on the first call. On subsequent calls you want the difference betweennow()
and the previous call toupdate
.