将 timedelta 格式化为字符串

2024-11-27 10:43:00
admin
原创
13
摘要:问题描述:我在格式化datetime.timedelta对象时遇到了麻烦。以下是我想做的事情:我有一个对象列表,对象类的成员之一是 timedelta 对象,它显示事件的持续时间。我想以小时:分钟的格式显示该持续时间。我尝试了多种方法来做到这一点,但都遇到了困难。我目前的方法是向我的对象类添加返回小时和分钟的...

问题描述:

我在格式化datetime.timedelta对象时遇到了麻烦。

以下是我想做的事情:我有一个对象列表,对象类的成员之一是 timedelta 对象,它显示事件的持续时间。我想以小时:分钟的格式显示该持续时间。

我尝试了多种方法来做到这一点,但都遇到了困难。我目前的方法是向我的对象类添加返回小时和分钟的方法。我可以通过将 timedelta.seconds 除以 3600 并四舍五入来得到小时数。我在获取余数秒并将其转换为分钟时遇到了麻烦。

顺便说一句,我正在使用带有 Django 模板的 Google AppEngine 进行演示。


解决方案 1:

您可以使用 将 timedelta 转换为字符串str()。以下是示例:

import datetime
start = datetime.datetime(2009,2,10,14,00)
end   = datetime.datetime(2009,2,10,16,00)
delta = end - start
print(str(delta))
# prints 2:00:00

解决方案 2:

如您所知,您可以通过访问属性从 timedelta 对象中获取 total_seconds .seconds

Python 提供了内置函数divmod(),可以执行以下操作:

s = 13420
hours, remainder = divmod(s, 3600)
minutes, seconds = divmod(remainder, 60)
print('{:02}:{:02}:{:02}'.format(int(hours), int(minutes), int(seconds)))
# result: 03:43:40

或者您可以使用模数和减法的组合来转换为小时和余数:

# arbitrary number of seconds
s = 13420
# hours
hours = s // 3600 
# remaining seconds
s = s - (hours * 3600)
# minutes
minutes = s // 60
# remaining seconds
seconds = s - (minutes * 60)
# total time
print('{:02}:{:02}:{:02}'.format(int(hours), int(minutes), int(seconds)))
# result: 03:43:40

解决方案 3:

>>> str(datetime.timedelta(hours=10.56))
10:33:36

>>> td = datetime.timedelta(hours=10.505) # any timedelta object
>>> ':'.join(str(td).split(':')[:2])
10:30

将对象传递timedeltastr()函数会调用与我们简单输入时相同的格式代码print td。由于您不需要秒数,我们可以用冒号(3 个部分)拆分字符串,然后仅使用前 2 个部分将其重新组合在一起。

解决方案 4:

我个人使用该humanize库来实现这一点:

>>> import datetime
>>> humanize.naturalday(datetime.datetime.now())
'today'
>>> humanize.naturalday(datetime.datetime.now() - datetime.timedelta(days=1))
'yesterday'
>>> humanize.naturalday(datetime.date(2007, 6, 5))
'Jun 05'
>>> humanize.naturaldate(datetime.date(2007, 6, 5))
'Jun 05 2007'
>>> humanize.naturaltime(datetime.datetime.now() - datetime.timedelta(seconds=1))
'a second ago'
>>> humanize.naturaltime(datetime.datetime.now() - datetime.timedelta(seconds=3600))
'an hour ago'

当然,它并没有给你你正在寻找的确切答案(事实上,str(timeA - timeB)但我发现,一旦超过几个小时,显示就会变得难以阅读。humanize支持更大的人类可读的值,并且也很好地本地化。

显然,它受到了 Djangocontrib.humanize模块的启发,所以既然您正在使用 Django,那么您应该使用它。

解决方案 5:

def td_format(td_object):
    seconds = int(td_object.total_seconds())
    periods = [
        ('year',        60*60*24*365),
        ('month',       60*60*24*30),
        ('day',         60*60*24),
        ('hour',        60*60),
        ('minute',      60),
        ('second',      1)
    ]

    strings=[]
    for period_name, period_seconds in periods:
        if seconds > period_seconds:
            period_value , seconds = divmod(seconds, period_seconds)
            has_s = 's' if period_value > 1 else ''
            strings.append("%s %s%s" % (period_value, period_name, has_s))

    return ", ".join(strings)

解决方案 6:

这是一个通用函数,用于将timedelta对象或常规数字(以秒或分钟等形式)转换为格式良好的字符串。我采纳了mpounsett对重复问题的精彩回答,使其更加灵活,提高了可读性,并添加了文档。

您会发现这是迄今为止最灵活的答案,因为它允许您:

  1. 动态自定义字符串格式,而不是硬编码。

  2. 省略某些时间间隔而不会出现问题(见下面的示例)。

功能:

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)

演示:

>>> 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

解决方案 7:

他已经有一个 timedelta 对象,那么为什么不使用其内置方法 total_seconds() 将其转换为秒,然后使用 divmod() 来获取小时和分钟?

hours, remainder = divmod(myTimeDelta.total_seconds(), 3600)
minutes, seconds = divmod(remainder, 60)

# Formatted only for hours and minutes as requested
print '%s:%s' % (hours, minutes)

无论时间增量是天还是年,这都是有效的。

解决方案 8:

我知道这是一个老问题了,但我用datetime.utcfromtimestamp()它来做这个。它需要花费数秒的时间并返回一个datetime可以像其他任何格式一样格式化的datetime

duration = datetime.utcfromtimestamp((end - begin).total_seconds())
print(duration.strftime('%H:%M'))

只要您保持在时间部分的合法范围内,这应该可以工作,即它不会返回 1234:35,因为小时数 <= 23。

解决方案 9:

我会认真考虑奥卡姆剃刀原则:

td = str(timedelta).split('.')[0]

这将返回一个不包含微秒的字符串

如果您想重新生成 datetime.timedelta 对象,只需执行以下操作:

h,m,s = re.split(':', td)
new_delta = datetime.timedelta(hours=int(h),minutes=int(m),seconds=int(s))

两年过去了,我爱上了这门语言!

解决方案 10:

我使用humanfriendlypython 库来做到这一点,效果非常好。

import humanfriendly
from datetime import timedelta
delta = timedelta(seconds = 321)
humanfriendly.format_timespan(delta)

'5 minutes and 21 seconds'

可在https://pypi.org/project/humanfriendly/获得

解决方案 11:

或许:

>>> import datetime
>>> dt0 = datetime.datetime(1,1,1)
>>> td = datetime.timedelta(minutes=34, hours=12, seconds=56)
>>> (dt0+td).strftime('%X')
'12:34:56'
>>> (dt0+td).strftime('%M:%S')
'34:56'
>>> (dt0+td).strftime('%H:%M')
'12:34'
>>>

解决方案 12:

我有一个功能:

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)

例子:

>>> 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'

解决方案 13:

我的datetime.timedelta对象超过了一天。所以这里还有另一个问题。上面的所有讨论都假设少于一天。Atimedelta实际上是天、秒和微秒的元组。上面的讨论应该td.seconds像 joe 那样使用,但是如果你有天,它就不会包含在秒值中。

我获取了两个日期时间之间的时间跨度并打印了日期和小时。

span = currentdt - previousdt
print '%d,%d
' % (span.days,span.seconds/3600)

解决方案 14:

提问者想要一种比典型格式更好的格式:

  >>> 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'

因此,实际上有两种格式,一种格式中天数为 0 且省略,另一种格式中出现文本“n 天,h:m:s”。但是,秒数可能有小数,并且打印输出中没有前导零,因此列会很混乱。

以下是我的日常生活,如果你喜欢的话:

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

这将返回以 dd:hh:mm:ss 格式的输出:

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

我确实考虑过增加年份,但这留给读者练习,因为输出超过 1 年也是安全的:

>>> str(datetime.timedelta(seconds=99999999))
'1157 days, 9:46:39'

解决方案 15:

按照上面 Joe 的示例值,我将使用模数算术运算符,如下:

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

请注意,Python 中的整数除法默认向下舍入;如果您想要更明确,请根据需要使用 math.floor() 或 math.ceil()。

解决方案 16:

一行代码。由于 timedeltas 不提供 datetime 的 strftime,因此将 timedelta 恢复为 datetime,并使用 stftime。

这不仅可以实现 OP 要求的“小时:分钟”格式,如果您的要求更改为另一种表示形式,现在您还可以利用 datetime 的 strftime 的全部格式化功能。

import datetime
td = datetime.timedelta(hours=2, minutes=10, seconds=5)
print(td)
print(datetime.datetime.strftime(datetime.datetime.strptime(str(td), "%H:%M:%S"), "%H:%M"))

Output:
2:10:05
02:10

这也解决了时间增量被格式化为 H:MM:SS 而不是 HH:MM:SS 的字符串的烦恼,这导致了我遇到这个问题,以及我分享的解决方案。

解决方案 17:

import datetime
hours = datetime.timedelta(hours=16, minutes=30)
print((datetime.datetime(1,1,1) + hours).strftime('%H:%M'))

解决方案 18:

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

解决方案 19:

我在工作中遇到过类似的加班计算输出问题。即使时间大于一天,值也可能为负数,该值也应始终以 HH:MM 格式显示。我结合了一些显示的解决方案,也许其他人会觉得这个解决方案有用。我意识到,如果 timedelta 值为负数,则大多数显示的解决方案(使用 divmod 方法)都无法立即使用:

def td2HHMMstr(td):
  '''Convert timedelta objects to a HH:MM string with (+/-) sign'''
  if td < datetime.timedelta(seconds=0):
    sign='-'
    td = -td
  else:
    sign = ''
  tdhours, rem = divmod(td.total_seconds(), 3600)
  tdminutes, rem = divmod(rem, 60)
  tdstr = '{}{:}:{:02d}'.format(sign, int(tdhours), int(tdminutes))
  return tdstr

timedelta 到 HH:MM 字符串:

td2HHMMstr(datetime.timedelta(hours=1, minutes=45))
'1:54'

td2HHMMstr(datetime.timedelta(days=2, hours=3, minutes=2))
'51:02'

td2HHMMstr(datetime.timedelta(hours=-3, minutes=-2))
'-3:02'

td2HHMMstr(datetime.timedelta(days=-35, hours=-3, minutes=-2))
'-843:02'

解决方案 20:

from django.utils.translation import ngettext

def localize_timedelta(delta):
    ret = []
    num_years = int(delta.days / 365)
    if num_years > 0:
        delta -= timedelta(days=num_years * 365)
        ret.append(ngettext('%d year', '%d years', num_years) % num_years)

    if delta.days > 0:
        ret.append(ngettext('%d day', '%d days', delta.days) % delta.days)

    num_hours = int(delta.seconds / 3600)
    if num_hours > 0:
        delta -= timedelta(hours=num_hours)
        ret.append(ngettext('%d hour', '%d hours', num_hours) % num_hours)

    num_minutes = int(delta.seconds / 60)
    if num_minutes > 0:
        ret.append(ngettext('%d minute', '%d minutes', num_minutes) % num_minutes)

    return ' '.join(ret)

这将产生:

>>> from datetime import timedelta
>>> localize_timedelta(timedelta(days=3660, minutes=500))
'10 years 10 days 8 hours 20 minutes'

解决方案 21:

针对此问题的直接模板过滤器。内置函数 int() 永远不会向上舍入。F 字符串(即 f'')需要 python 3.6。

@app_template_filter()
def diffTime(end, start):
    diff = (end - start).total_seconds()
    d = int(diff / 86400)
    h = int((diff - (d * 86400)) / 3600)
    m = int((diff - (d * 86400 + h * 3600)) / 60)
    s = int((diff - (d * 86400 + h * 3600 + m *60)))
    if d > 0:
        fdiff = f'{d}d {h}h {m}m {s}s'
    elif h > 0:
        fdiff = f'{h}h {m}m {s}s'
    elif m > 0:
        fdiff = f'{m}m {s}s'
    else:
        fdiff = f'{s}s'
    return fdiff

解决方案 22:

我继续MarredCheese 的回答,并添加了year,,monthmillicesond`microsecond`

除 之外的所有数字均格式化为整数,因此可以自定义second秒的分数。

@kfmfe04 要求几分之一秒,所以我发布了这个解决方案

其中main有一些例子。

from string import Formatter
from datetime import timedelta

def strfdelta(tdelta, fmt='{D:02}d {H:02}h {M:02}m {S:02.0f}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.0f}s' --> '05d 08h 04m 02s' (default)
        '{W}w {D}d {H}:{M:02}:{S:02.0f}'     --> '4w 5d 8:04:02'
        '{D:2}d {H:2}:{M:02}:{S:02.0f}'      --> ' 5d  8:04:02'
        '{H}h {S:.0f}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 = tdelta.total_seconds()
    elif inputtype in ['s', 'seconds']:
        remainder = float(tdelta)
    elif inputtype in ['m', 'minutes']:
        remainder = float(tdelta)*60
    elif inputtype in ['h', 'hours']:
        remainder = float(tdelta)*3600
    elif inputtype in ['d', 'days']:
        remainder = float(tdelta)*86400
    elif inputtype in ['w', 'weeks']:
        remainder = float(tdelta)*604800

    f = Formatter()
    desired_fields = [field_tuple[1] for field_tuple in f.parse(fmt)]
    possible_fields = ('Y','m','W', 'D', 'H', 'M', 'S', 'mS', 'µS')
    constants = {'Y':86400*365.24,'m': 86400*30.44 ,'W': 604800, 'D': 86400, 'H': 3600, 'M': 60, 'S': 1, 'mS': 1/pow(10,3) , 'µS':1/pow(10,6)}
    values = {}
    for field in possible_fields:
        if field in desired_fields and field in constants:
            Quotient, remainder = divmod(remainder, constants[field])
            values[field] = int(Quotient) if field != 'S' else Quotient + remainder
    return f.format(fmt, **values)

if __name__ == "__main__":
    td = timedelta(days=717, hours=3, minutes=5, seconds=8, microseconds=3549)
    print(strfdelta(td,'{Y} years {m} months {W} weeks {D} days {H:02}:{M:02}:{S:02}'))  
    print(strfdelta(td,'{m} months {W} weeks {D} days {H:02}:{M:02}:{S:02.4f}'))  
    td = timedelta( seconds=8, microseconds=8549)
    print(strfdelta(td,'{S} seconds {mS} milliseconds {µS} microseconds'))  
    print(strfdelta(td,'{S:.0f} seconds {mS} milliseconds {µS} microseconds'))  
    print(strfdelta(pow(10,7),inputtype='s'))

输出:

1 years 11 months 2 weeks 3 days 01:09:56.00354900211096
23 months 2 weeks 3 days 00:12:20.0035
8.008549 seconds 8 milliseconds 549 microseconds
8 seconds 8 milliseconds 549 microseconds
115d 17h 46m 40s

解决方案 23:

如果您的软件包中恰好有IPython​​ (您应该有),它有一个非常好的持续时间格式化程序 (以浮点秒为单位) (到目前为止)。它用于各种地方,例如单元格%%time魔法。我喜欢它为短持续时间生成的格式:

>>> from IPython.core.magics.execution import _format_time
>>> 
>>> for v in range(-9, 10, 2):
...     dt = 1.25 * 10**v
...     print(_format_time(dt))

1.25 ns
125 ns
12.5 µs
1.25 ms
125 ms
12.5 s
20min 50s
1d 10h 43min 20s
144d 16h 13min 20s
14467d 14h 13min 20s

解决方案 24:

timedelta 转换为字符串,用于打印运行时间信息。

def strfdelta_round(tdelta, round_period='second'):
  """timedelta to string,  use for measure running time
  attend period from days downto smaller period, round to minimum period
  omit zero value period  
  """
  period_names = ('day', 'hour', 'minute', 'second', 'millisecond')
  if round_period not in period_names:
    raise Exception(f'round_period "{round_period}" invalid, should be one of {",".join(period_names)}')
  period_seconds = (86400, 3600, 60, 1, 1/pow(10,3))
  period_desc = ('days', 'hours', 'mins', 'secs', 'msecs')
  round_i = period_names.index(round_period)
  
  s = ''
  remainder = tdelta.total_seconds()
  for i in range(len(period_names)):
    q, remainder = divmod(remainder, period_seconds[i])
    if int(q)>0:
      if not len(s)==0:
        s += ' '
      s += f'{q:.0f} {period_desc[i]}'
    if i==round_i:
      break
    if i==round_i+1:
      s += f'{remainder} {period_desc[round_i]}'
      break
    
  return s

例如自动省略零前导句点:

>>> td = timedelta(days=0, hours=2, minutes=5, seconds=8, microseconds=3549)
>>> strfdelta_round(td, 'second')
'2 hours 5 mins 8 secs'

或省略中间零点周期:

>>> td = timedelta(days=2, hours=0, minutes=5, seconds=8, microseconds=3549)
>>> strfdelta_round(td, 'millisecond')
'2 days 5 mins 8 secs 3 msecs'

或四舍五入到分钟,省略以下分钟:

>>> td = timedelta(days=1, hours=2, minutes=5, seconds=8, microseconds=3549)
>>> strfdelta_round(td, 'minute')
'1 days 2 hours 5 mins'

解决方案 25:

这是一个将 timedelta.total_seconds() 字符串化的函数。它适用于 Python 2 和 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'
        )

示例输出:

>>> 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

解决方案 26:

我想这样做,所以写了一个简单的函数。它对我来说非常有用,而且用途广泛(支持从年到微秒以及任何粒度级别,例如,您可以在“2 天 4 小时 48 分钟”和“2 天 4 小时”和“2 天 4.8 小时”之间进行选择,等等。

def pretty_print_timedelta(t, max_components=None, max_decimal_places=2):
''' 
Print a pretty string for a timedelta. 
For example datetime.timedelta(days=2, seconds=17280) will be printed as '2 days, 4 hours, 48 minutes'. Setting max_components to e.g. 1 will change this to '2.2 days', where the 
number of decimal points can also be set. 
'''
time_scales = [timedelta(days=365), timedelta(days=1), timedelta(hours=1), timedelta(minutes=1), timedelta(seconds=1), timedelta(microseconds=1000), timedelta(microseconds=1)]
time_scale_names_dict = {timedelta(days=365): 'year',  
                         timedelta(days=1): 'day', 
                         timedelta(hours=1): 'hour', 
                         timedelta(minutes=1): 'minute', 
                         timedelta(seconds=1): 'second', 
                         timedelta(microseconds=1000): 'millisecond', 
                         timedelta(microseconds=1): 'microsecond'}
count = 0
txt = ''
first = True
for scale in time_scales:
    if t >= scale: 
        count += 1
        if count == max_components:
            n = t / scale
        else:
            n = int(t / scale)
            
        t -= n*scale
        
        n_txt = str(round(n, max_decimal_places))
        if n_txt[-2:]=='.0': n_txt = n_txt[:-2]
        txt += '{}{} {}{}'.format('' if first else ', ', n_txt, time_scale_names_dict[scale], 's' if n>1 else '', )
        if first:
            first = False
        
        
if len(txt) == 0: 
    txt = 'none'
return txt

解决方案 27:

请检查此功能 - 它将 timedelta 对象转换为字符串“HH:MM:SS”

def format_timedelta(td):
    hours, remainder = divmod(td.total_seconds(), 3600)
    minutes, seconds = divmod(remainder, 60)
    hours, minutes, seconds = int(hours), int(minutes), int(seconds)
    if hours < 10:
        hours = '0%s' % int(hours)
    if minutes < 10:
        minutes = '0%s' % minutes
    if seconds < 10:
        seconds = '0%s' % seconds
    return '%s:%s:%s' % (hours, minutes, seconds)

解决方案 28:

我遇到了同样的问题,并且正在使用 pandas Timedelta,不想引入额外的依赖项(另一个答案提到humanfriendly),所以我编写了这个小函数来仅打印出相关信息:

def format_timedelta(td: pd.Timedelta) -> str:
    if pd.isnull(td):
        return str(td)
    else:
        c = td.components._asdict()
        return ", ".join(f"{n} {unit}" for unit, n in c.items() if n)

例如,pd.Timedelta(hours=3, seconds=12)将打印为3 hours, 12 seconds

解决方案 29:

这是我的简单解决方案,其中考虑了天数和填充

def td_format(td, pad=True):
    try:
        _days, parsed = str(td).split(",")
    except ValueError:
        hours, minutes, seconds = str(td).split(":")
    else:
        days = _days.split(" ")[0]
        _hours, minutes, seconds = parsed.split(":")
        hours = int(_hours) + int(days) * 24

    if pad:
        hours = hours.zfill(2)
        
    return f"{hours}:{minutes}:{seconds}"
>>> from datetime import timedelta
>>>
>>> td_format(timedelta(minutes=600))
'10:00:00'
>>> td_format(timedelta(hours=25))
'25:00:00'
>>> td_format(timedelta(minutes=144))
'02:24:00'
>>> td_format(timedelta(hours=2), pad=False)
'2:00:00'

解决方案 30:

如果您已经有一个 timedelta obj,那么只需将该 obj 转换为字符串。删除字符串的最后 3 个字符并打印。这将截断秒部分并以“小时:分钟”格式打印其余部分。

t = str(timedeltaobj) 

print t[:-3]
相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   642  
  引言在当今快速变化的科技市场中,企业要想保持竞争力,就必须具备高效的产品开发流程。小米作为一家以创新驱动的科技公司,其集成产品开发(IPD)流程在业界颇受关注。其中,技术路线图规划作为IPD流程的核心环节,对于确保产品技术领先、满足市场需求以及实现长期战略目标至关重要。本文将深入探讨小米IPD流程中的技术路线图规划,分...
华为IPD是什么   0  
  在当今快速变化的商业环境中,项目管理的高效执行是企业成功的关键。为了应对日益复杂的产品开发挑战,企业纷纷寻求将产品开发流程(Product Development Process, PDCP)与集成产品开发(Integrated Product Development, IPD)流程相结合的策略,以实现更高效、更协同的...
IPD管理   0  
  在当今竞争激烈的市场环境中,提高客户满意度是企业持续发展和成功的关键。为了实现这一目标,企业需要不断优化其产品开发和管理流程。IPD(Integrated Product Development,集成产品开发)流程图作为一种高效的项目管理工具,能够帮助企业实现跨部门协作、优化资源配置,并最终提升客户满意度。本文将深入探...
IPD流程是谁发明的   0  
  在项目管理领域,集成产品开发(IPD, Integrated Product Development)流程被视为提升项目成功率的关键框架。IPD通过其系统化的方法,将产品开发过程中的各个阶段紧密连接,确保从概念到市场的每一步都经过深思熟虑和高效执行。本文将深入探讨IPD流程的六个核心阶段如何深刻影响项目成功,并为项目管...
IPD流程中CDCP   0  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用