Format timedelta to string

后端 未结 28 2333
春和景丽
春和景丽 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:23

    Here is a general purpose function for converting either a timedelta object or a regular number (in the form of seconds or minutes, etc.) to a nicely formatted string. I took mpounsett's fantastic answer on a duplicate question, made it a bit more flexible, improved readibility, and added documentation.

    You will find that it is the most flexible answer here so far since it allows you to:

    1. Customize the string format on the fly instead of it being hard-coded.
    2. Leave out certain time intervals without a problem (see examples below).

    Function:

    from string import Formatter
    from datetime import timedelta
    
    def strfdelta(tdelta, fmt='{D:02}d {H:02}h {M:02}m {S:02}s', inputtype='timedelta'):
        """Convert a datetime.timedelta object or a regular number to a custom-
        formatted string, just like the stftime() method does for datetime.datetime
        objects.
    
        The fmt argument allows custom formatting to be specified.  Fields can 
        include seconds, minutes, hours, days, and weeks.  Each field is optional.
    
        Some examples:
            '{D:02}d {H:02}h {M:02}m {S:02}s' --> '05d 08h 04m 02s' (default)
            '{W}w {D}d {H}:{M:02}:{S:02}'     --> '4w 5d 8:04:02'
            '{D:2}d {H:2}:{M:02}:{S:02}'      --> ' 5d  8:04:02'
            '{H}h {S}s'                       --> '72h 800s'
    
        The inputtype argument allows tdelta to be a regular number instead of the  
        default, which is a datetime.timedelta object.  Valid inputtype strings: 
            's', 'seconds', 
            'm', 'minutes', 
            'h', 'hours', 
            'd', 'days', 
            'w', 'weeks'
        """
    
        # Convert tdelta to integer seconds.
        if inputtype == 'timedelta':
            remainder = int(tdelta.total_seconds())
        elif inputtype in ['s', 'seconds']:
            remainder = int(tdelta)
        elif inputtype in ['m', 'minutes']:
            remainder = int(tdelta)*60
        elif inputtype in ['h', 'hours']:
            remainder = int(tdelta)*3600
        elif inputtype in ['d', 'days']:
            remainder = int(tdelta)*86400
        elif inputtype in ['w', 'weeks']:
            remainder = int(tdelta)*604800
    
        f = Formatter()
        desired_fields = [field_tuple[1] for field_tuple in f.parse(fmt)]
        possible_fields = ('W', 'D', 'H', 'M', 'S')
        constants = {'W': 604800, 'D': 86400, 'H': 3600, 'M': 60, 'S': 1}
        values = {}
        for field in possible_fields:
            if field in desired_fields and field in constants:
                values[field], remainder = divmod(remainder, constants[field])
        return f.format(fmt, **values)
    

    Demo:

    >>> td = timedelta(days=2, hours=3, minutes=5, seconds=8, microseconds=340)
    
    >>> print strfdelta(td)
    02d 03h 05m 08s
    
    >>> print strfdelta(td, '{D}d {H}:{M:02}:{S:02}')
    2d 3:05:08
    
    >>> print strfdelta(td, '{D:2}d {H:2}:{M:02}:{S:02}')
     2d  3:05:08
    
    >>> print strfdelta(td, '{H}h {S}s')
    51h 308s
    
    >>> print strfdelta(12304, inputtype='s')
    00d 03h 25m 04s
    
    >>> print strfdelta(620, '{H}:{M:02}', 'm')
    10:20
    
    >>> print strfdelta(49, '{D}d {H}h', 'h')
    2d 1h
    

提交回复
热议问题