我在格式化日期时间时遇到了麻烦。timedelta对象。

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

我尝试了各种方法来做这件事,但我有困难。我目前的方法是为返回小时和分钟的对象在类中添加方法。我可以通过除以time得到小时数。秒乘以3600,四舍五入。我在得到剩余的秒并将其转换为分钟时遇到了麻烦。

顺便说一下,我使用谷歌AppEngine和Django模板来表示。


当前回答

我有同样的问题,我使用熊猫Timedeltas,不想带来额外的依赖关系(另一个答案提到人类友好),所以我写了这个小函数只打印出相关信息:

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小时12秒。

其他回答

# Format seconds to days, hours, minutes and seconds string
def ptime(seconds):
if(seconds >= 86400):
    d = seconds // 86400 # // floor division
    return (f"{round(d)}d") + ptime(seconds - d * 86400)
else:
    if(seconds >= 3600):
        h = seconds // 3600 
        return (f"{round(h)}h") + ptime(seconds - h * 3600)
    else:
        if(seconds >= 60):
            m = seconds // 60
            return(f"{round(m)}m" + ptime(seconds - m * 60))
        else:
            if (seconds > 0):
                return(f"{round(seconds)}s")
            else:
                return("")

我想这样做,所以写了一个简单的函数。它对我来说非常有用,而且非常通用(支持年到微秒,以及任何粒度级别,例如,你可以选择“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

请检查这个函数-它将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)

我有一个函数:

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