1

I'd like to compare two date times with an exact string output such as "3 hours, 2, minutes, 46 seconds". Now, say I have two datetime objects in UTC, I need them to be able to be an arbitrary amount but still cut off unneeded values. Example:

>>> import datetime
>>> date1 = datetime.datetime.now()
>>> date2 = datetime.datetime.fromtimestamp(123456789)
>>> date2 - date1
datetime.timedelta(-16362, 59566, 655021)

Now I could just use datetime.datetime.strftime() as a follow up but with the wide range of values I can encounter (1 second to months) I want to cut off the unneeded values and avoid "0 months, 0 weeks... etc." and "1 hour, 0 minutes, 0 seconds" without rounding (values are always positive). Is there an effient way to dynamically do this to only show relevent time values? I've looked through other questions similar to How do I find the time difference between two datetime objects in python? but none fully answer my question and I cannot figure it out on my own after many hours of tinkering.

Matthew
  • 21
  • 3
  • Exactly which values are "relevant" and which are "unneeded"? For example, if you just want resolution down to the day, you can use the `datetime.date()` method to convert to a `date` object. – jwodder Sep 16 '18 at 05:12
  • I'm almost certain that this would need to be done with your own function. datetime objects have attributes for `months`, etc. so you would need to implement these yourself. – IllustriousMagenta Sep 16 '18 at 05:25
  • @jwodder If I am given a date which is "4 hours, 0 minutes, and 10 seconds" difference to the current time, I don't want to return the "0 minutes". Same goes for not wanting to return "0 days" but adding that if there *are* days. Basically I want to return all values which do not have a value equal to zero – Matthew Sep 16 '18 at 16:45

1 Answers1

1

Question: ... do this to only show relevent time values?

The following implements your own class Timedelta:

class Timedelta(object):
    def __init__(self, td):
        self._td = td

        def _calc(s, f):
            _s = int(s % f)
            return _s, int(s / f)

        s, self.hours = _calc(self._td.seconds, (60 * 60))
        self.seconds, self.minutes = _calc(s, 60)

    def __str__(self):
        r = ""
        for v in [('Days', self._td.days), ('Hours', self.hours), ('Minutes', self.minutes), ('Seconds', self.seconds)]:
            if v[1] != 0:
                lingua = v[0]
                if v[1] == 1: lingua = v[0][:-1]
                r += "{} {} ".format(v[1], lingua)
        return  r

    def __repr__(self):
        return "({}) Days:{} Hours:{} Minutes:{} Seconds:{}"\
            .format((self._td.seconds), self._td.days, self.hours, self.minutes, self.seconds)

Usage:

date1 = dt.datetime(2018, 9, 17, hour=18, minute=23, second=0)
date2 = dt.datetime(2018, 9, 17, hour=22, minute=23, second=10)
dtt = date2 - date1
print("dtt:{}".format(dtt))

tdelta = Timedelta(date2 - date1)
print("Timedelta::\__repr\__: {}".format(tdelta.__repr__()))
print("Timedelta::\__str\__: {}".format(tdelta))

Output:

dtt:4:00:10
Timedelta::__repr__: (14410) Days:0 Hours:4 Minutes:0 Seconds:10
Timedelta:__str__: 4 Hours 10 Seconds

Tested with Python:3.4.2

stovfl
  • 14,998
  • 7
  • 24
  • 51