"""TimeSpan"""
# Author: Michal Ciesielczyk
# Licence: MIT
import datetime
[docs]class TimeSpan(datetime.timedelta):
"""Represents a time span.
All arguments are optional and default to 0. Arguments may be integers or
floats, and may be positive or negative.
As in the base :py:class:`python:datetime.timedelta` class, only days,
seconds and microseconds are stored internally. Arguments are converted to
those units:
- A millisecond is converted to 1000 microseconds.
- A minute is converted to 60 seconds.
- An hour is converted to 3600 seconds.
and days, seconds and microseconds are then normalized so that the
representation is unique.
If any argument is a float and there are fractional microseconds, the
fractional microseconds left over from all arguments are combined and their
sum is rounded to the nearest microsecond using round-half-to-even
tiebreaker.
:param float,optional seconds: number of seconds in the time span.
:param float,optional microseconds: number of microseconds in the time span.
:param float,optional milliseconds: number of milliseconds in the time span.
:param float,optional minutes: number of minutes in the time span.
:param float,optional hours: number of hours in the time span.
:param float,optional days: number of days in the time span.
"""
def __new__(cls, seconds=0, microseconds=0, milliseconds=0,
minutes=0, hours=0, days=0):
return datetime.timedelta.__new__(cls, days=days, seconds=seconds,
microseconds=microseconds,
milliseconds=milliseconds,
minutes=minutes, hours=hours)
[docs] def total_hours(self):
"""Total hours in the duration."""
return (self.days * 24 + self.seconds / 3600 +
self.microseconds / 3600000000)
[docs] def total_minutes(self):
"""Total minutes in the duration."""
return (self.days * 1440 + self.seconds / 60 +
self.microseconds / 60000000)
[docs] def total_milliseconds(self):
"""Total milliseconds in the duration."""
return (self.days * 86400000 + self.seconds * 1000 +
self.microseconds / 1000)
[docs] def human_str(self, trim_zeros=True):
"""Returns a human-readable :py:class:`~.timespan.TimeSpan` object,
represented as time units such as days, hours, minutes, and seconds.
:param bool,optional trim_zeros: indicates whether the leading zeros
in the result should be skipped
:return: human-readable time span
:rtype: str
"""
if self.total_seconds() < 1:
return "{:d} ms".format(self.microseconds // 1000)
human = []
if self.days > 0 or not trim_zeros:
human.append("{:d} days".format(self.days))
units = [("hours", 3600), ("mins", 60), ("secs", 1)]
seconds_left = self.seconds
for name, secs in units:
if trim_zeros and self.seconds < secs:
continue
value = seconds_left // secs
seconds_left %= secs
if value == 1:
name = name.rstrip('s')
human.append("{:d} {:s}".format(value, name))
return ', '.join(human)