在Python中将秒转换为hh:mm:ss

在Python中将秒转换为hh:mm:ss,python,django,time,Python,Django,Time,如何将int(秒数)转换为格式mm:ss或hh:mm:ss 我需要用Python代码(如果可能的话,在Django模板中)来实现这一点 SilentGhost的答案包含了我的答案遗漏的细节,并在此处重新发布: >>> a = datetime.timedelta(seconds=65) datetime.timedelta(0, 65) >>> str(a) '0:01:05' 除了Python内置了对日期和时间的支持(参见bigmattyh的回复),从秒中

如何将int(秒数)转换为格式mm:sshh:mm:ss

我需要用Python代码(如果可能的话,在Django模板中)来实现这一点

SilentGhost的答案包含了我的答案遗漏的细节,并在此处重新发布:

>>> a = datetime.timedelta(seconds=65)
datetime.timedelta(0, 65)
>>> str(a)
'0:01:05'

除了Python内置了对日期和时间的支持(参见bigmattyh的回复),从秒中查找分钟或小时也很容易:

minutes = seconds / 60
hours = minutes / 60

现在,当您想要显示分或秒时,将它们修改为60,这样它们就不会大于59,而不是Python人员,但是没有任何库的最简单方法就是:

total   = 3800
seconds = total % 60
total   = total - seconds
hours   = total / 3600
total   = total - (hours * 3600)
mins    = total / 60

您可以通过简单的除法从秒数计算分钟数和小时数:

seconds = 12345
minutes = seconds // 60
hours = minutes // 60

print "%02d:%02d:%02d" % (hours, minutes % 60, seconds % 60)
print "%02d:%02d" % (minutes, seconds % 60)
# 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
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)

这里
/
是Python的整数除法。

在除以60时要小心:整数之间的除法返回一个整数-> 12/60=0,除非您从future导入分部。 以下是从Python 2.6.2复制和粘贴的内容:

IDLE 2.6.2      
>>> 12/60
0
>>> from __future__ import division
>>> 12/60
0.20000000000000001

执行请求的代码,带有示例,并显示如何处理他未指定的案例:

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"

你可以——也应该——把它存储为时间增量而不是int,但是这是一个单独的问题,时间增量实际上并不能使这一特定任务变得更容易。

< P>我不能相信任何答案都给出了我认为“一个显而易见的方法去做”(我甚至不是荷兰人……-)--不超过24小时的秒数(具体为86399秒):

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

根据您的具体需要,在应用程序中为此格式化任务定义自定义筛选器可能更方便。

如果您使用divmod,您将不受不同类型整数除法的影响:

seconds = 12345
minutes = seconds // 60
hours = minutes // 60

print "%02d:%02d:%02d" % (hours, minutes % 60, seconds % 60)
print "%02d:%02d" % (minutes, seconds % 60)
# 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
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

如果需要经常这样做,可以预先计算一天中所有可能的字符串的秒数:

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字符串

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))
这需要多少内存<列表的code>sys.getsizeof不起作用,因为它只提供列表的大小及其str引用,而不包括str本身的内存:

# 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
691,249
0.12218026108523448
如果我们只有一个大str呢?每个值的长度正好为8个字符,因此我们可以将该str切片,并获得当天第二个X的正确str:

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))
印刷品:

5,657,616
691,249
0.12218026108523448
减少到这么多:

print(str_size / list_size)
印刷品:

5,657,616
691,249
0.12218026108523448
在性能方面,这看起来像是一个经典的内存与CPU权衡:

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

分钟是模60,所以它总是<60,所以小时==0…哦,对不起,这意味着之后要做这一步。。。意志fix@sth当前位置SilentGhost拥有deets。我认为datetime中的任何东西都不能满足他的要求。没有什么比得上timedelta.strftime,所以即使他将他的“秒数”存储为timedelta(他可能应该这样做),他仍然必须自己进行格式化。将其转换为时间将是一个难题,因为他似乎有一定的时间量(timedelta),而不是一天中的某个时间(time)。@Glenn:str()表示法有什么问题?@Glenn:从这个问题上可以清楚地看出,格式要求是相当不稳定的。转换成字符串并对
h:mm:ss
感到满意要容易得多,然后用大量肮脏的黑客试图得到
hh:mm:ss
;它询问如何将秒转换为两种特定的格式,几乎每个人的回答都不符合他的要求。按照他的要求格式化这个文件并不需要任何接近黑客的东西。@Glenn:这很好。。。如果OP想要进一步格式化它,它并不是从这里开始的火箭科学。它不能回答他的问题,也不能提供任何能让他对问题有一个好答案的东西——充其量你只能手动预加一个0或去掉“0:”,这根本不是一个好的解决方案(取决于时间差。_str__行为,据我所知,该行为未在任何地方指定,因此可能会更改)所以,是的。我想你只是没有抓住要点,OP需要可读格式的秒数。这才是重要的。@Glenn:伙计,你在你理想主义的高台上杀了我。它确实回答了他的问题,即使这不是完美的模型。(手动添加或预加“0”并不是一个沉重的负担。)他没有说“像这样格式化”,而是给出了具体的格式。我无法计算我用这种方式格式化的次数。编辑字符串意味着您取决于timedelta的字符串格式的具体行为(如果s[0:2]==“0::…),这是个坏主意。也许timedelta不会决定将其格式化为“h.mm.ss”现在在某些地区,但没有人说将来不能。这只是一个糟糕的方法。你可以使用divmod.Nope来缩短计算时间。而不是pythonic。虽然这是一个小问题,可能与OP
time.strftime(“%H:%M:%s',time.gmtime(864001))无关
返回一个令人讨厌的惊喜。是的,只工作了一天——当然,你的解决方案也一样,它会以不同的方式分解,而不是“环绕”,因为
str(datetime.timedelta(seconds=86400))
说“1天”;-):)我认为我的解决方案不会崩溃,它仍然提供最可读的输出,由于OP没有参与这里的讨论,我可以自由地假设这正是他想要的。Re“…众多答案中的任何一个”:你的意思是“…众多答案中的任何一个”?正如@AlexMartelli所说,如果秒数超过一天,这将无法正常工作。另外,
str(