我该如何将一个整数(表示秒数)转换为mm:ss或hh:mm:ss格式?
我需要使用Python代码来实现此功能(如果可能的话,还可以在Django模板中实现)。
我无法相信任何一个答案都可以给出我认为的“显而易见的方法”(我甚至不是荷兰人...!-)——最多只有23小时59分59秒的秒数(特定地86399秒):
>>> import time
>>> time.strftime('%H:%M:%S', time.gmtime(12345))
'03:25:45'
在Django模板中实现这个功能稍微有些麻烦,因为time
过滤器支持奇怪的时间格式语法(我相信这是受PHP启发的),同时需要datetime模块和时区实现库pytz来准备数据。例如:
>>> from django import template as tt
>>> import pytz
>>> import datetime
>>> tt.Template('{{ x|time:"H:i:s" }}').render(
... tt.Context({'x': datetime.datetime.fromtimestamp(12345, pytz.utc)}))
u'03:25:45'
根据您的需要,可能更方便在您的应用程序中定义一个自定义过滤器来执行此格式化任务。
>>> a = datetime.timedelta(seconds=65)
datetime.timedelta(0, 65)
>>> str(a)
'0:01:05'
请阅读 datetime 模块文档。
SilentGhost 的回答详细介绍了我的回答遗漏的内容,这里进行转载:
>>> a = datetime.timedelta(seconds=65)
datetime.timedelta(0, 65)
>>> str(a)
'0:01:05'
.zfill(7)
就可以解决。 - Skippy le Grand Gourou代码执行了要求的功能,提供了示例,并展示了如何处理他没有指定的情况:
def format_seconds_to_hhmmss(seconds):
hours = seconds // (60*60)
seconds %= (60*60)
minutes = seconds // 60
seconds %= 60
return "%02i:%02i:%02i" % (hours, minutes, seconds)
def format_seconds_to_mmss(seconds):
minutes = seconds // 60
seconds %= 60
return "%02i:%02i" % (minutes, seconds)
minutes = 60
hours = 60*60
assert format_seconds_to_mmss(7*minutes + 30) == "07:30"
assert format_seconds_to_mmss(15*minutes + 30) == "15:30"
assert format_seconds_to_mmss(1000*minutes + 30) == "1000:30"
assert format_seconds_to_hhmmss(2*hours + 15*minutes + 30) == "02:15:30"
assert format_seconds_to_hhmmss(11*hours + 15*minutes + 30) == "11:15:30"
assert format_seconds_to_hhmmss(99*hours + 15*minutes + 30) == "99:15:30"
assert format_seconds_to_hhmmss(500*hours + 15*minutes + 30) == "500:15:30"
你可以 - 而且很可能应该 - 将这个值存储为 timedelta 而不是 int,但这是一个独立的问题,并且使用 timedelta 实际上并不能使这个特定任务更容易。
通过简单的除法,您可以从秒数计算出分钟数和小时数:
seconds = 12345
minutes = seconds // 60
hours = minutes // 60
print "%02d:%02d:%02d" % (hours, minutes % 60, seconds % 60)
print "%02d:%02d" % (minutes, seconds % 60)
这里的//
是Python中的整数除法。
# show time strings for 3800 seconds
# easy way to get mm:ss
print "%02d:%02d" % divmod(3800, 60)
# easy way to get hh:mm:ss
from functools import reduce
print "%02d:%02d:%02d" % \
reduce(lambda ll,b : divmod(ll[0],b) + ll[1:],
[(3800,),60,60])
# function to convert floating point number of seconds to
# hh:mm:ss.sss
def secondsToStr(t):
return "%02d:%02d:%02d.%03d" % \
reduce(lambda ll,b : divmod(ll[0],b) + ll[1:],
[(round(t*1000),),1000,60,60])
print secondsToStr(3800.123)
输出:
63:20
01:03:20
01:03:20.123
在进行60的除法时要小心:整数之间的除法会返回一个整数-> 12/60 = 0,除非你从未来导入除法。以下是从Python 2.6.2复制并粘贴的内容:
IDLE 2.6.2
>>> 12/60
0
>>> from __future__ import division
>>> 12/60
0.20000000000000001
虽然我不是 Python 的专家,但最简单的方法就是不使用任何库:
total = 3800
seconds = total % 60
total = total - seconds
hours = total / 3600
total = total - (hours * 3600)
mins = total / 60
try:
from itertools import product
except ImportError:
def product(*seqs):
if len(seqs) == 1:
for p in seqs[0]:
yield p,
else:
for s in seqs[0]:
for p in product(*seqs[1:]):
yield (s,) + p
hhmmss = []
for (h, m, s) in product(range(24), range(60), range(60)):
hhmmss.append("%02d:%02d:%02d" % (h, m, s))
现在将秒转换为格式字符串是一个快速的索引查找:
print hhmmss[12345]
打印
'03:25:45'
编辑:
已更新到2020年,删除了Py2兼容性问题和f-strings!
import sys
from itertools import product
hhmmss = [f"{h:02d}:{m:02d}:{s:02d}"
for h, m, s in product(range(24), range(60), range(60))]
# we can still just index into the list, but define as a function
# for common API with code below
seconds_to_str = hhmmss.__getitem__
print(seconds_to_str(12345))
sys.getsizeof
无法计算,因为它只会给出列表及其字符串引用的大小,但不包括字符串本身的内存:# how big is a list of 24*60*60 8-character strs?
list_size = sys.getsizeof(hhmmss) + sum(sys.getsizeof(s) for s in hhmmss)
print("{:,}".format(list_size))
打印:
5,657,616
hhmmss_str = ''.join([f"{h:02d}:{m:02d}:{s:02d}"
for h, m, s in product(range(24),
range(60),
range(60))])
def seconds_to_str(n):
loc = n * 8
return hhmmss_str[loc: loc+8]
print(seconds_to_str(12345))
这样做有节省空间吗?
# how big is a str of 24*60*60*8 characters?
str_size = sys.getsizeof(hhmmss_str)
print("{:,}".format(str_size))
打印:
691,249
缩小到大约这么多:
print(str_size / list_size)
打印:
0.12218026108523448
import timeit
print("\nindex into pre-calculated list")
print(timeit.timeit("hhmmss[6]", '''from itertools import product; hhmmss = [f"{h:02d}:{m:02d}:{s:02d}"
for h, m, s in product(range(24),
range(60),
range(60))]'''))
print("\nget slice from pre-calculated str")
print(timeit.timeit("hhmmss_str[6*8:7*8]", '''from itertools import product; hhmmss_str=''.join([f"{h:02d}:{m:02d}:{s:02d}"
for h, m, s in product(range(24),
range(60),
range(60))])'''))
print("\nuse datetime.timedelta from stdlib")
print(timeit.timeit("timedelta(seconds=6)", "from datetime import timedelta"))
print("\ninline compute of h, m, s using divmod")
print(timeit.timeit("n=6;m,s=divmod(n,60);h,m=divmod(m,60);f'{h:02d}:{m:02d}:{s:02d}'"))
index into pre-calculated list
0.0434853
get slice from pre-calculated str
0.1085147
use datetime.timedelta from stdlib
0.7625738
inline compute of h, m, s using divmod
2.0477764
minutes = seconds / 60
hours = minutes / 60
time.strftime('%H:%M:%S', time.gmtime(864001))
返回了一个令人不悦的意外结果。 - SilentGhoststr(datetime.timedelta(seconds = 86400))
表示“1天”;-) - Alex Martellistr(datetime.timedelta(seconds=<number>))
会更加优雅。 - Granny Aching