Format timedelta to string

后端 未结 28 1673
春和景丽
春和景丽 2020-11-22 03:57

I\'m having trouble formatting a datetime.timedelta object.

Here\'s what I\'m trying to do: I have a list of objects and one of the members of the cl

相关标签:
28条回答
  • 2020-11-22 04:07

    I used the humanfriendly python library to do this, it works very well.

    import humanfriendly
    from datetime import timedelta
    delta = timedelta(seconds = 321)
    humanfriendly.format_timespan(delta)
    
    '5 minutes and 21 seconds'
    

    Available at https://pypi.org/project/humanfriendly/

    0 讨论(0)
  • 2020-11-22 04:07
    def seconds_to_time_left_string(total_seconds):
        s = int(total_seconds)
        years = s // 31104000
        if years > 1:
            return '%d years' % years
        s = s - (years * 31104000)
        months = s // 2592000
        if years == 1:
            r = 'one year'
            if months > 0:
                r += ' and %d months' % months
            return r
        if months > 1:
            return '%d months' % months
        s = s - (months * 2592000)
        days = s // 86400
        if months == 1:
            r = 'one month'
            if days > 0:
                r += ' and %d days' % days
            return r
        if days > 1:
            return '%d days' % days
        s = s - (days * 86400)
        hours = s // 3600
        if days == 1:
            r = 'one day'
            if hours > 0:
                r += ' and %d hours' % hours
            return r 
        s = s - (hours * 3600)
        minutes = s // 60
        seconds = s - (minutes * 60)
        if hours >= 6:
            return '%d hours' % hours
        if hours >= 1:
            r = '%d hours' % hours
            if hours == 1:
                r = 'one hour'
            if minutes > 0:
                r += ' and %d minutes' % minutes
            return r
        if minutes == 1:
            r = 'one minute'
            if seconds > 0:
                r += ' and %d seconds' % seconds
            return r
        if minutes == 0:
            return '%d seconds' % seconds
        if seconds == 0:
            return '%d minutes' % minutes
        return '%d minutes and %d seconds' % (minutes, seconds)
    
    for i in range(10):
        print pow(8, i), seconds_to_time_left_string(pow(8, i))
    
    
    Output:
    1 1 seconds
    8 8 seconds
    64 one minute and 4 seconds
    512 8 minutes and 32 seconds
    4096 one hour and 8 minutes
    32768 9 hours
    262144 3 days
    2097152 24 days
    16777216 6 months
    134217728 4 years
    
    0 讨论(0)
  • 2020-11-22 04:07

    Here's a function to stringify timedelta.total_seconds(). It works in python 2 and 3.

    def strf_interval(seconds):
        days, remainder = divmod(seconds, 86400)
        hours, remainder = divmod(remainder, 3600)
        minutes, seconds = divmod(remainder, 60)
        return '{} {} {} {}'.format(
                "" if int(days) == 0 else str(int(days)) + ' days',
                "" if int(hours) == 0 else str(int(hours)) + ' hours',
                "" if int(minutes) == 0 else str(int(minutes))  + ' mins',
                "" if int(seconds) == 0 else str(int(seconds))  + ' secs'
            )
    

    Example output:

    >>> print(strf_interval(1))
       1 secs
    >>> print(strf_interval(100))
      1 mins 40 secs
    >>> print(strf_interval(1000))
      16 mins 40 secs
    >>> print(strf_interval(10000))
     2 hours 46 mins 40 secs
    >>> print(strf_interval(100000))
    1 days 3 hours 46 mins 40 secs
    
    0 讨论(0)
  • 2020-11-22 04:10

    Questioner wants a nicer format than the typical:

      >>> import datetime
      >>> datetime.timedelta(seconds=41000)
      datetime.timedelta(0, 41000)
      >>> str(datetime.timedelta(seconds=41000))
      '11:23:20'
      >>> str(datetime.timedelta(seconds=4102.33))
      '1:08:22.330000'
      >>> str(datetime.timedelta(seconds=413302.33))
      '4 days, 18:48:22.330000'
    

    So, really there's two formats, one where days are 0 and it's left out, and another where there's text "n days, h:m:s". But, the seconds may have fractions, and there's no leading zeroes in the printouts, so columns are messy.

    Here's my routine, if you like it:

    def printNiceTimeDelta(stime, etime):
        delay = datetime.timedelta(seconds=(etime - stime))
        if (delay.days > 0):
            out = str(delay).replace(" days, ", ":")
        else:
            out = "0:" + str(delay)
        outAr = out.split(':')
        outAr = ["%02d" % (int(float(x))) for x in outAr]
        out   = ":".join(outAr)
        return out
    

    this returns output as dd:hh:mm:ss format:

    00:00:00:15
    00:00:00:19
    02:01:31:40
    02:01:32:22
    

    I did think about adding years to this, but this is left as an exercise for the reader, since the output is safe at over 1 year:

    >>> str(datetime.timedelta(seconds=99999999))
    '1157 days, 9:46:39'
    
    0 讨论(0)
  • 2020-11-22 04:11

    Following Joe's example value above, I'd use the modulus arithmetic operator, thusly:

    td = datetime.timedelta(hours=10.56)
    td_str = "%d:%d" % (td.seconds/3600, td.seconds%3600/60)
    

    Note that integer division in Python rounds down by default; if you want to be more explicit, use math.floor() or math.ceil() as appropriate.

    0 讨论(0)
  • 2020-11-22 04:12

    I have a function:

    def period(delta, pattern):
        d = {'d': delta.days}
        d['h'], rem = divmod(delta.seconds, 3600)
        d['m'], d['s'] = divmod(rem, 60)
        return pattern.format(**d)
    

    Examples:

    >>> td = timedelta(seconds=123456789)
    >>> period(td, "{d} days {h}:{m}:{s}")
    '1428 days 21:33:9'
    >>> period(td, "{h} hours, {m} minutes and {s} seconds, {d} days")
    '21 hours, 33 minutes and 9 seconds, 1428 days'
    
    0 讨论(0)
提交回复
热议问题