Python函数将秒转换为分钟、小时和天
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4048651/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Python function to convert seconds into minutes, hours, and days
提问by yoyoyo
Question: Write a program that asks the user to enter a number of seconds, and works as follows:
问题:编写一个程序,要求用户输入秒数,其工作原理如下:
There are 60 seconds in a minute. If the number of seconds entered by the user is greater than or equal to 60, the program should display the number of minutes in that many seconds.
There are 3600 seconds in an hour. If the number of seconds entered by the user is greater than or equal to 3600, the program should display the number of hours in that many seconds.
There are 86400 seconds in a day. If the number of seconds entered by the user is greater than or equal to 86400, the program should display the number of days in that many seconds.
一分钟有 60 秒。如果用户输入的秒数大于或等于 60,则程序应显示该秒数中的分钟数。
一小时有 3600 秒。如果用户输入的秒数大于或等于 3600,则程序应显示该秒数中的小时数。
一天有 86400 秒。如果用户输入的秒数大于或等于 86400,则程序应显示该秒数中的天数。
What I have so far:
到目前为止我所拥有的:
def time():
sec = int( input ('Enter the number of seconds:'.strip())
if sec <= 60:
minutes = sec // 60
print('The number of minutes is {0:.2f}'.format(minutes))
if sec (<= 3600):
hours = sec // 3600
print('The number of minutes is {0:.2f}'.format(hours))
if sec <= 86400:
days = sec // 86400
print('The number of minutes is {0:.2f}'.format(days))
return
回答by lalli
Do it the other way around subtracting the secs as needed, and don't call it time; there's a package with that name:
反过来做,根据需要减去秒,不要称之为时间;有一个同名的包:
def sec_to_time():
sec = int( input ('Enter the number of seconds:'.strip()) )
days = sec / 86400
sec -= 86400*days
hrs = sec / 3600
sec -= 3600*hrs
mins = sec / 60
sec -= 60*mins
print days, ':', hrs, ':', mins, ':', sec
回答by Garrett Hyde
This will convert nseconds into ddays, hhours, mminutes, and sseconds.
这会将n秒转换为d天、h小时、m分钟和s秒。
from datetime import datetime, timedelta
def GetTime():
sec = timedelta(seconds=int(input('Enter the number of seconds: ')))
d = datetime(1,1,1) + sec
print("DAYS:HOURS:MIN:SEC")
print("%d:%d:%d:%d" % (d.day-1, d.hour, d.minute, d.second))
回答by admica
At first glance, I figured divmod would be faster since it's a single statement and a built-in function, but timeit seems to show otherwise. Consider this little example I came up with when I was trying to figure out the fastest method for use in a loop that continuously runs in a gobject idle_add splitting a seconds counter into a human readable time for updating a progress bar label.
乍一看,我认为 divmod 会更快,因为它是一个单一的语句和一个内置函数,但 timeit 似乎另有说明。考虑这个小例子,当我试图找出在循环中使用的最快方法时,该循环在 gobject idle_add 中连续运行,将秒计数器拆分为人类可读的时间以更新进度条标签。
import timeit
def test1(x,y, dropy):
while x > 0:
y -= dropy
x -= 1
# the test
minutes = (y-x) / 60
seconds = (y-x) % 60.0
def test2(x,y, dropy):
while x > 0:
y -= dropy
x -= 1
# the test
minutes, seconds = divmod((y-x), 60)
x = 55 # litte number, also number of tests
y = 10000 # make y > x by factor of drop
dropy = 7 # y is reduced this much each iteration, for variation
print "division and modulus:", timeit.timeit( lambda: test1(x,y,dropy) )
print "divmod function:", timeit.timeit( lambda: test2(x,y,dropy) )
The built-in divmod function seems incredibly slower compared to using the simple division and modulus.
与使用简单的除法和取模相比,内置的 divmod 函数似乎慢得令人难以置信。
division and modulus: 12.5737669468
divmod function: 17.2861430645
回答by Mr. B
This tidbit is useful for displaying elapsed time to varying degrees of granularity.
这个花絮对于以不同的粒度显示经过的时间很有用。
I personally think that questions of efficiency are practically meaningless here, so long as something grossly inefficient isn't being done. Premature optimization is the root of quite a bit of evil. This is fast enough that it'll never be your choke point.
我个人认为,效率问题在这里实际上毫无意义,只要没有做一些非常低效的事情。过早的优化是许多罪恶的根源。这足够快,它永远不会成为你的瓶颈。
intervals = (
('weeks', 604800), # 60 * 60 * 24 * 7
('days', 86400), # 60 * 60 * 24
('hours', 3600), # 60 * 60
('minutes', 60),
('seconds', 1),
)
def display_time(seconds, granularity=2):
result = []
for name, count in intervals:
value = seconds // count
if value:
seconds -= value * count
if value == 1:
name = name.rstrip('s')
result.append("{} {}".format(value, name))
return ', '.join(result[:granularity])
..and this provides decent output:
..这提供了不错的输出:
In [52]: display_time(1934815)
Out[52]: '3 weeks, 1 day'
In [53]: display_time(1934815, 4)
Out[53]: '3 weeks, 1 day, 9 hours, 26 minutes'
回答by Pete Forman
These functions are fairly compact and only use standard Python 2.6 and later.
这些函数相当紧凑,仅使用标准 Python 2.6 及更高版本。
def ddhhmmss(seconds):
"""Convert seconds to a time string "[[[DD:]HH:]MM:]SS".
"""
dhms = ''
for scale in 86400, 3600, 60:
result, seconds = divmod(seconds, scale)
if dhms != '' or result > 0:
dhms += '{0:02d}:'.format(result)
dhms += '{0:02d}'.format(seconds)
return dhms
def seconds(dhms):
"""Convert a time string "[[[DD:]HH:]MM:]SS" to seconds.
"""
components = [int(i) for i in dhms.split(':')]
pad = 4 - len(components)
if pad < 0:
raise ValueError('Too many components to match [[[DD:]HH:]MM:]SS')
components = [0] * pad + components
return sum(i * j for i, j in zip((86400, 3600, 60, 1), components))
And here are tests to go with them. I'm using the pytest package as a simple way to test exceptions.
这是与他们一起进行的测试。我使用 pytest 包作为测试异常的简单方法。
import ddhhmmss
import pytest
def test_ddhhmmss():
assert ddhhmmss.ddhhmmss(0) == '00'
assert ddhhmmss.ddhhmmss(2) == '02'
assert ddhhmmss.ddhhmmss(12 * 60) == '12:00'
assert ddhhmmss.ddhhmmss(3600) == '01:00:00'
assert ddhhmmss.ddhhmmss(10 * 86400) == '10:00:00:00'
assert ddhhmmss.ddhhmmss(86400 + 5 * 3600 + 30 * 60 + 1) == '01:05:30:01'
assert ddhhmmss.ddhhmmss(365 * 86400) == '365:00:00:00'
def test_seconds():
assert ddhhmmss.seconds('00') == 0
assert ddhhmmss.seconds('02') == 2
assert ddhhmmss.seconds('12:00') == 12 * 60
assert ddhhmmss.seconds('01:00:00') == 3600
assert ddhhmmss.seconds('1:0:0') == 3600
assert ddhhmmss.seconds('3600') == 3600
assert ddhhmmss.seconds('60:0') == 3600
assert ddhhmmss.seconds('10:00:00:00') == 10 * 86400
assert ddhhmmss.seconds('1:05:30:01') == 86400 + 5 * 3600 + 30 * 60 + 1
assert ddhhmmss.seconds('365:00:00:00') == 365 * 86400
def test_seconds_raises():
with pytest.raises(ValueError):
ddhhmmss.seconds('')
with pytest.raises(ValueError):
ddhhmmss.seconds('foo')
with pytest.raises(ValueError):
ddhhmmss.seconds('1:00:00:00:00')
回答by Pavv
seconds_in_day = 86400
seconds_in_hour = 3600
seconds_in_minute = 60
seconds = int(input("Enter a number of seconds: "))
days = seconds // seconds_in_day
seconds = seconds - (days * seconds_in_day)
hours = seconds // seconds_in_hour
seconds = seconds - (hours * seconds_in_hour)
minutes = seconds // seconds_in_minute
seconds = seconds - (minutes * seconds_in_minute)
print("{0:.0f} days, {1:.0f} hours, {2:.0f} minutes, {3:.0f} seconds.".format(
days, hours, minutes, seconds))
回答by Danda
#1 min = 60
#1 hour = 60 * 60 = 3600
#1 day = 60 * 60 * 24 = 86400
x=input('enter a positive integer: ')
t=int(x)
day= t//86400
hour= (t-(day*86400))//3600
minit= (t - ((day*86400) + (hour*3600)))//60
seconds= t - ((day*86400) + (hour*3600) + (minit*60))
print( day, 'days' , hour,' hours', minit, 'minutes',seconds,' seconds')
回答by Premysl Vorac
To convert seconds (as string) into datetime, this could also help. You get number of days and seconds. Seconds can be further converted into minutes and hours.
要将秒(作为字符串)转换为日期时间,这也有帮助。你得到天数和秒数。秒可以进一步转换为分钟和小时。
from datetime import datetime, timedelta
sec = timedelta(seconds=(int(input('Enter the number of seconds: '))))
time = str(sec)
回答by Highstaker
I'm not entirely sure if you want it, but I had a similar task and needed to remove a field if it is zero. For example, 86401 seconds would show "1 days, 1 seconds" instead of "1 days, 0 hours, 0 minutes, 1 seconds". THe following code does that.
我不完全确定你是否想要它,但我有一个类似的任务,如果它为零,需要删除一个字段。例如,86401 秒将显示“1 天 1 秒”而不是“1 天 0 小时 0 分 1 秒”。下面的代码就是这样做的。
def secondsToText(secs):
days = secs//86400
hours = (secs - days*86400)//3600
minutes = (secs - days*86400 - hours*3600)//60
seconds = secs - days*86400 - hours*3600 - minutes*60
result = ("{} days, ".format(days) if days else "") + \
("{} hours, ".format(hours) if hours else "") + \
("{} minutes, ".format(minutes) if minutes else "") + \
("{} seconds, ".format(seconds) if seconds else "")
return result
EDIT: a slightly better version that handles pluralization of words.
编辑:处理单词复数的稍微好一点的版本。
def secondsToText(secs):
days = secs//86400
hours = (secs - days*86400)//3600
minutes = (secs - days*86400 - hours*3600)//60
seconds = secs - days*86400 - hours*3600 - minutes*60
result = ("{0} day{1}, ".format(days, "s" if days!=1 else "") if days else "") + \
("{0} hour{1}, ".format(hours, "s" if hours!=1 else "") if hours else "") + \
("{0} minute{1}, ".format(minutes, "s" if minutes!=1 else "") if minutes else "") + \
("{0} second{1}, ".format(seconds, "s" if seconds!=1 else "") if seconds else "")
return result
EDIT2: created a gistthat does that in several languages
EDIT2:创建了一个以多种语言执行此操作的要点
回答by Ralph Bolton
Patching Mr.B's answer(sorry, not enough rep. to comment), we can return variable granularity based on the amount of time. For example, we don't say "1 week, 5 seconds", we just say "1 week":
修补 B 先生的答案(抱歉,没有足够的代表发表评论),我们可以根据时间量返回可变粒度。例如,我们不说“1 周,5 秒”,我们只说“1 周”:
def display_time(seconds, granularity=2):
result = []
for name, count in intervals:
value = seconds // count
if value:
seconds -= value * count
if value == 1:
name = name.rstrip('s')
result.append("{} {}".format(value, name))
else:
# Add a blank if we're in the middle of other values
if len(result) > 0:
result.append(None)
return ', '.join([x for x in result[:granularity] if x is not None])
Some sample input:
一些示例输入:
for diff in [5, 67, 3600, 3605, 3667, 24*60*60, 24*60*60+5, 24*60*60+57, 24*60*60+3600, 24*60*60+3667, 2*24*60*60, 2*24*60*60+5*60*60, 7*24*60*60, 7*24*60*60 + 24*60*60]:
print "For %d seconds: %s" % (diff, display_time(diff, 2))
...returns this output:
...返回此输出:
For 5 seconds: 5 seconds
For 67 seconds: 1 minute, 7 seconds
For 3600 seconds: 1 hour
For 3605 seconds: 1 hour
For 3667 seconds: 1 hour, 1 minute
For 86400 seconds: 1 day
For 86405 seconds: 1 day
For 86457 seconds: 1 day
For 90000 seconds: 1 day, 1 hour
For 90067 seconds: 1 day, 1 hour
For 172800 seconds: 2 days
For 190800 seconds: 2 days, 5 hours
For 604800 seconds: 1 week
For 691200 seconds: 1 week, 1 day

