maw*_*wcs 246 python string format datetime timedelta
我是一个Python新手(2周),我在格式化datetime.timedelta对象时遇到了麻烦.
这是我正在尝试做的事情:我有一个对象列表,该对象类的一个成员是一个timedelta对象,显示事件的持续时间.我希望以小时:分钟的格式显示该持续时间.
我已经尝试了各种方法来做到这一点,我遇到了困难.我目前的方法是为我的对象添加方法,返回小时和分钟.我可以通过将timedelta.seconds除以3600并将其四舍五入来获得小时数.我无法获得余数秒并将其转换为分钟.
顺便说一句,我正在使用Google AppEngine它Django Templates进行演示.
如果有人可以帮助或知道更好的解决方法,我会非常高兴.
谢谢,
Par*_*and 202
您可以使用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
Run Code Online (Sandbox Code Playgroud)
Joh*_*uhy 166
如您所知,您可以通过访问.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
Run Code Online (Sandbox Code Playgroud)
或者你可以使用模数和减法的组合转换为小时和余数:
# 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
Run Code Online (Sandbox Code Playgroud)
joe*_*ker 56
>>> 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
Run Code Online (Sandbox Code Playgroud)
将timedelta对象传递给str()函数会调用与我们只需键入时相同的格式代码print td.由于您不需要秒数,我们可以用冒号(3个部分)拆分字符串,然后将它与仅前两个部分放回原处.
小智 39
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)
Run Code Online (Sandbox Code Playgroud)
Bil*_*idd 26
他已经有了一个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)
Run Code Online (Sandbox Code Playgroud)
无论时间增量是否有几天或几年,这都有效.
ana*_*cat 23
我个人使用这个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'
Run Code Online (Sandbox Code Playgroud)
当然,它不会给你确切地你要找的人(这是确实的答案str(timeA - timeB),但我发现,一旦你超越了几个小时,显示变得不可读很快.humanize对那些更大价值的支持人类可读,也很好地本地化.
它的灵感来自Django的contrib.humanize模块,显然,因为你使用Django,你应该使用它.
Mar*_*ese 18
这是一个通用函数,用于将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)
Run Code Online (Sandbox Code Playgroud)
演示:
>>> 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
Run Code Online (Sandbox Code Playgroud)
sjn*_*ngm 17
我知道这是一个陈旧的问题,但我用datetime.utcfromtimestamp()它.它需要秒数并返回一个datetime可以像任何其他格式一样的格式datetime.
duration = datetime.utcfromtimestamp(end - begin)
print duration.strftime('%H:%M')
Run Code Online (Sandbox Code Playgroud)
只要您保持时间部分的合法范围,这应该有效,即它不会返回1234:35,因为小时<= 23.
Kev*_*ice 15
发问者想要比典型的更好的格式:
>>> 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'
Run Code Online (Sandbox Code Playgroud)
所以,真的有两种格式,一种是天数为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
Run Code Online (Sandbox Code Playgroud)
这将输出返回为dd:hh:mm:ss格式:
00:00:00:15
00:00:00:19
02:01:31:40
02:01:32:22
Run Code Online (Sandbox Code Playgroud)
我确实考虑过多年才能做到这一点,但这是留给读者的练习,因为输出安全超过1年:
>>> str(datetime.timedelta(seconds=99999999))
'1157 days, 9:46:39'
Run Code Online (Sandbox Code Playgroud)
Goo*_*JaY 15
我有一个功能:
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)
Run Code Online (Sandbox Code Playgroud)
例子:
>>> 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'
Run Code Online (Sandbox Code Playgroud)
小智 13
我的datetime.timedelta物品超过了一天.所以这是另一个问题.上面的所有讨论都假设不到一天.A timedelta实际上是天,秒和微秒的元组.上面的讨论应该td.seconds像乔一样使用,但是如果你有几天它不包括在秒值中.
我在2个日期时间和打印日期和时间之间得到了一段时间.
span = currentdt - previousdt
print '%d,%d\n' % (span.days,span.seconds/3600)
Run Code Online (Sandbox Code Playgroud)
Pyr*_*erm 12
我会认真考虑奥卡姆的剃刀方法:
td = str(timedelta).split('.')[0]
Run Code Online (Sandbox Code Playgroud)
这将返回不带微秒的字符串
如果要重新生成datetime.timedelta对象,只需执行以下操作:
h,m,s = re.split(':', td)
new_delta = datetime.timedelta(hours=int(h),minutes=int(m),seconds=int(s))
Run Code Online (Sandbox Code Playgroud)
2年了,我喜欢这门语言!
按照Joe上面的示例值,我将使用模数算术运算符,因此:
td = datetime.timedelta(hours=10.56)
td_str = "%d:%d" % (td.seconds/3600, td.seconds%3600/60)
Run Code Online (Sandbox Code Playgroud)
请注意,默认情况下,Python中的整数除法向下舍入; 如果您想更明确,请根据需要使用math.floor()或math.ceil().
我使用humanfriendlypython库来做到这一点,它工作得很好。
import humanfriendly
from datetime import timedelta
delta = timedelta(seconds = 321)
humanfriendly.format_timespan(delta)
'5 minutes and 21 seconds'
Run Code Online (Sandbox Code Playgroud)
可在https://pypi.org/project/humanfriendly/
小智 6
import datetime
hours = datetime.timedelta(hours=16, minutes=30)
print((datetime.datetime(1,1,1) + hours).strftime('%H:%M'))
Run Code Online (Sandbox Code Playgroud)
小智 5
此问题的直接模板过滤器。内置函数 int() 永远不会四舍五入。F-Strings(即 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
Run Code Online (Sandbox Code Playgroud)
一艘班轮。由于 timedeltas 不提供 datetime 的 strftime,因此将 timedelta 返回为 datetime,并使用 stftime。
这不仅可以实现 OP 请求的格式“小时:分钟”,现在,如果您的要求更改为其他表示形式,您还可以利用日期时间的 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
Run Code Online (Sandbox Code Playgroud)
这也解决了时间增量被格式化为字符串为 H:MM:SS 而不是 HH:MM:SS 的烦恼,这导致了我遇到这个问题,以及我分享的解决方案。
也许:
>>> 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'
>>>
Run Code Online (Sandbox Code Playgroud)
maw*_*wcs -14
感谢大家的帮助。我收集了您的许多想法并将它们放在一起,让我知道您的想法。
我向该类添加了两个方法,如下所示:
def hours(self):
retval = ""
if self.totalTime:
hoursfloat = self.totalTime.seconds / 3600
retval = round(hoursfloat)
return retval
def minutes(self):
retval = ""
if self.totalTime:
minutesfloat = self.totalTime.seconds / 60
hoursAsMinutes = self.hours() * 60
retval = round(minutesfloat - hoursAsMinutes)
return retval
Run Code Online (Sandbox Code Playgroud)
在我的 django 中,我使用了这个( sum 是对象,它在字典中):
<td>{{ sum.0 }}</td>
<td>{{ sum.1.hours|stringformat:"d" }}:{{ sum.1.minutes|stringformat:"#02.0d" }}</td>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
253366 次 |
| 最近记录: |