我有一个以秒为单位返回信息的函数,但我需要以小时:分钟:秒存储该信息。
有没有简单的方法可以在Python中将秒转换为这种格式?
可在如何在Python中将H:MM:SS时间字符串转换为秒的方法中找到此问题的反义词。
您可以使用datetime.timedelta函数:
1
2
3>>> import datetime
>>> str(datetime.timedelta(seconds=666))
'0:11:06'
恕我直言,这是最好的方法,因为您随后可以对timedelta和任何datetime对象使用算术运算。
这可以工作多天:str(datetime.timedelta(seconds=60*60*24+1)) = 1 day, 0:00:01
str(datetime.timedelta(seconds=round(666666.55)))正确显示天;限制小数秒。
timedelta不是溢出安全的,并且不能正确执行数学运算,例如str(timedelta(hours=8) - timedelta(hours=10))结果为-1 day, 22:00:00,基于整数的解决方案正是针对需要-02:00:00的情况的。
+1。这个答案很容易修改。例如,如果要在打印时忽略某个字段,请使用以下命令:stackoverflow.com/questions/7999935/
要显示2位数小时,只需添加zfill(8)。 str(datetime.timedelta(seconds=666)).zfill(8) 00:11:06
通过使用divmod()函数,该函数仅进行一次除法以同时产生商和余数,您只需执行两个数学运算就可以非常快速地得到结果:
1
2m, s = divmod(seconds, 60)
h, m = divmod(m, 60)
然后使用字符串格式将结果转换为所需的输出:
1
2print('{:d}:{:02d}:{:02d}'.format(h, m, s)) # Python 3
print(f'{h:d}:{m:02d}:{s:02d}') # Python 3.6+
如果您更喜欢运算符而不是函数,请使用模。例如(仅分钟/秒):%d:%02dmn % (seconds 60, seconds % 60)
您可以将其扩展到几天:d, h = divmod(h, 24)。
@MarkRansom:然后到m, d = divmod(m, 31)个月。糟糕,您不能。更糟糕的是,如果leap秒进入游戏,您的代码将是错误的。长话短说:使用timedelta并不要弄乱日历,它会咬你。
@Tibo timedelta处理leap秒吗?我怀疑不是。在许多应用程序中,这种简单的数学运算绰绰有余。
@MarkRansom str(timedelta(hours=8) - timedelta(hours=10))结果是-1天,22:00:00所以... idk如果它适用于leap秒,但不适用于负数。
如何对熊猫数据框中的列执行此操作?
@Tibo:不幸的是,您不能,因为time(0, 0) + timedelta(anything)是TypeError。您可以使用datetime而不是time,然后使用.time()方法进行转换,但是如果该方法意外溢出,它将无提示地执行"错误操作"。
@Tibo的注释的至少第一部分应作为注释附加到答案。尽管我同意这是简单数学的一种很好的方法,并且可以完美地计算持续到几天的持续时间,但它会失败,即几个月。可能需要额外注意的是,不应将这种解决方案与用于处理datetime对象的任何函数的替代方法混淆。
它以小函数def s2hhmmss(s): m, s = divmod(s, 60) h, m = divmod(m, 60) return str(int(h)).zfill(2) + : + str(int(m)).zfill(2) + : + str(int(s)).zfill(2)的形式出现
对于那些讨论日期时间的人:请注意,最初的问题是不希望将小时数分解为更大的时间单位,因此,如果创建的时间单位大于小时数,则需要手动将其减少为整数小时。
为了使用格式更容易格式化:timestamp = {0:02}:{1:02}:{2:02}.format(h, m, s)
我很难说出这种简单的方法(至少我不记得语法),但是可以使用time.strftime,它提供了对格式的更多控制:
1
2
3
4
5
6
7
8from time import strftime
from time import gmtime
strftime("%H:%M:%S", gmtime(666))
'00:11:06'
strftime("%H:%M:%S", gmtime(60*60*24))
'00:00:00'
gmtime用于将秒转换为strftime()所需的特殊元组格式。
Note: Truncates after 23:59:59
好吧,答案实际上是在这里提供的-stackoverflow.com/questions/1384406/
不幸的是,此方法从1开始测量天数,因此它不能用来表示时间增量,因此这是一个等待发生的事故。例如,对于time.strftime(%d %H:%M:%S, time.gmtime(1)) => 1天,0:00:01。
使用datetime:
使用':0>8'格式:
1
2
3
4
5
6
7
8
9
10from datetime import timedelta
"{:0>8}".format(str(timedelta(seconds=66)))
# Result: '00:01:06'
"{:0>8}".format(str(timedelta(seconds=666777)))
# Result: '7 days, 17:12:57'
"{:0>8}".format(str(timedelta(seconds=60*60*49+109)))
# Result: '2 days, 1:01:49'
没有':0>8'格式:
1
2
3
4
5
6
7
8"{}".format(str(timedelta(seconds=66)))
# Result: '00:01:06'
"{}".format(str(timedelta(seconds=666777)))
# Result: '7 days, 17:12:57'
"{}".format(str(timedelta(seconds=60*60*49+109)))
# Result: '2 days, 1:01:49'
使用time:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17from time import gmtime
from time import strftime
# NOTE: The following resets if it goes over 23:59:59!
strftime("%H:%M:%S", gmtime(125))
# Result: '00:02:05'
strftime("%H:%M:%S", gmtime(60*60*24-1))
# Result: '23:59:59'
strftime("%H:%M:%S", gmtime(60*60*24))
# Result: '00:00:00'
strftime("%H:%M:%S", gmtime(666777))
# Result: '17:12:57'
# Wrong
如果增量少于一秒钟,它将失败:"{:0>8}".format(timedelta(milliseconds=66)) 0:00:00.066000
对于其他所有人:without :0>8:示例缺少前导0。{:0>8}零填充到左边的8个零。
在python 3.5.2中,我收到TypeError。我正在格式化time.time()-start变量。有见识吗? TypeError: non-empty format string passed to object.__format__
我尝试使用datetime.now()而不是time.time()来生成我的timedelta对象,并且遇到相同的错误。
@ medley56使用Python3时,如果要使用诸如0>8:"{:0>8}".format(str(datetime.timedelta(seconds=666777)))之类的格式,则需要使用str()。 检查此答案以获取更多信息。
这是我的快速技巧:
1
2
3
4from humanfriendly import format_timespan
secondsPassed = 1302
format_timespan(secondsPassed)
# '21 minutes and 42 seconds'
有关更多信息,请访问:
如果需要获取datetime.time值,则可以使用以下技巧:
1my_time = (datetime(1970,1,1) + timedelta(seconds=my_seconds)).time()
您不能将timedelta添加到time,但是可以将其添加到datetime。
UPD:同一技术的另一种变化:
1my_time = (datetime.fromordinal(1) + timedelta(seconds=my_seconds)).time()
可以使用大于0的任何数字来代替1。在这里,我们使用datetime.fromordinal总是返回datetime对象且time组件为零的事实。
这就是我的方法。
1
2
3
4
5
6
7
8
9
10
11
12
13
14def sec2time(sec, n_msec=3):
''' Convert seconds to 'D days, HH:MM:SS.FFF' '''
if hasattr(sec,'__len__'):
return [sec2time(s) for s in sec]
m, s = divmod(sec, 60)
h, m = divmod(m, 60)
d, h = divmod(h, 24)
if n_msec > 0:
pattern = '%%02d:%%02d:%%0%d.%df' % (n_msec+3, n_msec)
else:
pattern = r'%02d:%02d:%02d'
if d == 0:
return pattern % (h, m, s)
return ('%d days, ' + pattern) % (d, h, m, s)
一些例子:
1
2
3
4
5
6
7
8
9
10
11$ sec2time(10, 3)
Out: '00:00:10.000'
$ sec2time(1234567.8910, 0)
Out: '14 days, 06:56:07'
$ sec2time(1234567.8910, 4)
Out: '14 days, 06:56:07.8910'
$ sec2time([12, 345678.9], 3)
Out: ['00:00:12.000', '4 days, 00:01:18.900']
与上面的答案相比,这有什么好处?str(datetime.timedelta(seconds=666))
@RiazRizvi为666.0和666.1值提供一致的字符串长度(以微秒为单位)。
如果需要访问浮点数的小时,分??钟和秒,dateutil.relativedelta也很方便。 datetime.timedelta没有提供类
似的接口。
1
2
3
4
5from dateutil.relativedelta import relativedelta
rt = relativedelta(seconds=5440)
print(rt.seconds)
print('{:02d}:{:02d}:{:02d}'.format(
int(rt.hours), int(rt.minutes), int(rt.seconds)))
打印
1
240.0
01:30:40
我从您那里得到了不同的输出,这让我觉得您有错字。 您可能打算使用seconds=5440而不是seconds=5540。 不过,我喜欢您的回答!
感谢您指出,@ J-L,现在已修复。
以下设置对我有用。
1
2
3
4
5
6
7
8
9
10
11
12
13def sec_to_hours(seconds):
a=str(seconds//3600)
b=str((seconds%3600)//60)
c=str((seconds%3600)%60)
d=["{} hours {} mins {} seconds".format(a, b, c)]
return d
print(sec_to_hours(10000))
# ['2 hours 46 mins 40 seconds']
print(sec_to_hours(60*60*24+105))
# ['24 hours 1 mins 45 seconds']