当前位置:  开发笔记 > 编程语言 > 正文

Python格式timedelta到字符串

如何解决《Python格式timedelta到字符串》经验,为你挑选了13个好方法。

我是一个Python新手(2周),我在格式化datetime.timedelta对象时遇到了麻烦.

这是我正在尝试做的事情:我有一个对象列表,该对象类的一个成员是一个timedelta对象,显示事件的持续时间.我希望以小时:分钟的格式显示该持续时间.

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

顺便说一句,我正在使用Google AppEngineDjango Templates进行演示.

如果有人可以帮助或知道更好的解决方法,我会非常高兴.

谢谢,



1> Parand..:

您可以使用str()将timedelta转换为字符串.这是一个例子:

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


更像是用timedelta作为参数调用str()方法.
当数据类型被定义为'datetime.timedelta'而你正在使用它时,你需要使用它``ConvertDuration = datetime.timedelta(milliseconds = int(254459))`然后你只需使用split来获得微秒的游戏.从**0:03:43.765000**我只需运行`TotalDuration = str(ConvertDuration).split('.',2)[0]即可获得**0:03:43**
你不需要那里的str调用,它将通过print自动完成.
这可能会将delta打印为字符串,但不会将其格式化为OP请求的格式.
@Zitrax但是如果要将delta与另一个字符串连接起来是必要的.例如`print'某事'+ str(delta)`
不需要拆分的第二个参数:`TotalDuration = str(ConvertDuration).split('。')[0]同样适用。

2> John Fouhy..:

如您所知,您可以通过访问.seconds属性从timedelta对象获取total_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


请注意,您实际上可能希望使用''%d:%02d:%02d'`在输出字符串中使用前导零.
如果差异可能是负数或超过24小时(`.seconds`属性忽略`.days`),请不要使用`.seconds`.使用`.total_seconds()`或其模拟代替.
对于python 2.7及更高版本,使用.total_seconds()方法
对于负时间,您应该首先评估符号,然后执行`abs(s)`.

3> joeforker..:
>>> 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

timedelta对象传递给str()函数会调用与我们只需键入时相同的格式代码print td.由于您不需要秒数,我们可以用冒号(3个部分)拆分字符串,然后将它与仅前两个部分放回原处.


如果它超过一天,它将在分割/加入处理之后格式化为例如"4天,8:00".
`str(my_timedelta)`对于负数而言效果不佳

4> 小智..:
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)


真的很好,我建议将“如果秒> period_seconds:”更改为“如果秒> = period_seconds:”。

5> Bill Kidd..:

他已经有了一个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)

无论时间增量是否有几天或几年,这都有效.



6> anarcat..:

我个人使用这个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对那些更大价值的支持人类可读,也很好地本地化.

它的灵感来自Django的contrib.humanize模块,显然,因为你使用Django,你应该使用它.


不错,+ 1虽然:humanize.naturaldelta(pd.Timedelta('-10sec'))-> '10 seconds':S ...
它*是*10秒*delta*.:)你想要*时间*,`naturaltime`是你想要使用的.

7> MarredCheese..:

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

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

    即时自定义字符串格式,而不是硬编码.

    留出一定的时间间隔没有问题(见下面的例子).

功能:

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



8> sjngm..:

我知道这是一个陈旧的问题,但我用datetime.utcfromtimestamp()它.它需要秒数并返回一个datetime可以像任何其他格式一样的格式datetime.

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

只要您保持时间部分的合法范围,这应该有效,即它不会返回1234:35,因为小时<= 23.


我非常喜欢这种解决方案,它可以让您控制格式。请注意,您也可以像这样直接使用str格式程序:“ {0:%H}:{0:%M}”。format(duration)

9> Kevin J. Ric..:

发问者想要比典型的更好的格式:

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



10> 小智..:

我的datetime.timedelta物品超过了一天.所以这是另一个问题.上面的所有讨论都假设不到一天.A timedelta实际上是天,秒和微秒的元组.上面的讨论应该td.seconds像乔一样使用,但是如果你有几天它不包括在秒值中.

我在2个日期时间和打印日期和时间之间得到了一段时间.

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



11> 小智..:

我会认真考虑奥卡姆的剃刀方法:

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

2年了,我喜欢这门语言!


这不包括天

12> UltraNurd..:

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

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

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


+1,但为什么不编辑使用//的答案?我还建议使用`td.total_seconds()`而不是`.seconds`使其适用于> 1天的间隔.
不要忘记//在Python 3000中截断除法

13> Dhiraj Gupta..:

我使用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/

推荐阅读
云聪京初瑞子_617
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有