简体   繁体   English

Function 将秒转换为分钟、小时和天

[英]Function to convert seconds into minutes, hours, and days

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.一分钟有60秒。 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.如果用户输入的秒数大于或等于 60,则程序应显示该秒数中的分钟数。

  • There are 3600 seconds in an hour.一小时有3600秒。 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.如果用户输入的秒数大于或等于 3600,则程序应显示该秒数中的小时数。

  • There are 86400 seconds in a day.一天有86400秒。 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.如果用户输入的秒数大于或等于 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

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'

This will convert n seconds into d days, h hours, m minutes, and s seconds.这会将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))

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)

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".例如,86401 秒将显示“1 天 1 秒”而不是“1 天 0 小时 0 分钟 1 秒”。 THe following code does that.下面的代码就是这样做的。

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 gist that does that in several languages EDIT2:创建了一个以多种语言执行此操作的要点

def seconds_to_dhms(time):
    seconds_to_minute   = 60
    seconds_to_hour     = 60 * seconds_to_minute
    seconds_to_day      = 24 * seconds_to_hour

    days    =   time // seconds_to_day
    time    %=  seconds_to_day

    hours   =   time // seconds_to_hour
    time    %=  seconds_to_hour

    minutes =   time // seconds_to_minute
    time    %=  seconds_to_minute

    seconds = time

    print("%d days, %d hours, %d minutes, %d seconds" % (days, hours, minutes, seconds))


time = int(input("Enter the number of seconds: "))
seconds_to_dhms(time)

Output: Enter the number of seconds: 2434234232输出:输入秒数:2434234232

Result: 28174 days, 0 hours, 10 minutes, 32 seconds结果: 28174 天 0 小时 10 分钟 32 秒

def normalize_seconds(seconds: int) -> tuple:
    (days, remainder) = divmod(seconds, 86400)
    (hours, remainder) = divmod(remainder, 3600)
    (minutes, seconds) = divmod(remainder, 60)

    return namedtuple("_", ("days", "hours", "minutes", "seconds"))(days, hours, minutes, seconds)
def convertSeconds(seconds):
    h = seconds//(60*60)
    m = (seconds-h*60*60)//60
    s = seconds-(h*60*60)-(m*60)
    return [h, m, s]

The function input is a number of seconds, and the return is a list of hours, minutes and seconds which that amount of seconds represent.函数输入是秒数,返回是一个小时、分钟和秒的列表,这些秒数代表。

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))

Although divmod() has been mentioned, I didn't see what I considered to be a nice example.尽管已经提到了 divmod(),但我没有看到我认为是一个很好的例子。 Here's mine:这是我的:

q=972021.0000  # For example
days = divmod(q, 86400) 
# days[0] = whole days and
# days[1] = seconds remaining after those days
hours = divmod(days[1], 3600)
minutes = divmod(hours[1], 60)
print "%i days, %i hours, %i minutes, %i seconds" % (days[0], hours[0], minutes[0], minutes[1])

Which outputs:哪个输出:

11 days, 6 hours, 0 minutes, 21 seconds
#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')

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.乍一看,我认为 divmod 会更快,因为它是一条语句和一个内置函数,但 timeit 似乎另有说明。 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.考虑一下这个小例子,当我试图找出在循环中使用的最快方法时,该方法在 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

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

Patching Mr.B's answer (sorry, not enough rep. to comment), we can return variable granularity based on the amount of time.修补Mr.B 的答案(抱歉,没有足够的代表发表评论),我们可以根据时间量返回可变粒度。 For example, we don't say "1 week, 5 seconds", we just say "1 week":例如,我们不说“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

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
time_in_sec = 65 #I took time as 65 sec for example 

day = divmod(time_in_sec, 86_400)
hour = divmod(day[1], 3_600)
min = divmod(hour[1], 60)
sec = min[1]

print(f"Day {day[0]} |Hour {hour[0]} |Min {min[0]} |Sec {sec}")

Explanation:解释:

divmod(x, y) function returns (x//y, x%y) divmod(x, y)函数返回(x//y, x%y)

In day variable the x//y is the number of days and the x%y is the remaining seconds.day变量中, x//y是天数, x%y是剩余秒数。

So for the hour variable the remainder of the day variable is the input.所以对于hour变量, day变量的其余部分是输入。 Likewise you can calculate up to a week using this simple program.同样,您可以使用这个简单的程序计算最多一周。

The "timeit" answer above that declares divmod to be slower has seriously flawed logic.上面声明 divmod 速度较慢的“timeit”答案存在严重的逻辑缺陷。

Test1 calls operators. Test1 调用操作员。

Test2 calls the function divmod, and calling a function has overhead. Test2调用函数divmod,调用函数有开销。

A more accurate way to test would be:更准确的测试方法是:

import timeit

def moddiv(a,b):
  q= a/b
  r= a%b
  return q,r

a=10
b=3
md=0
dm=0
for i in range(1,10):
  c=a*i
  md+= timeit.timeit( lambda: moddiv(c,b))
  dm+=timeit.timeit( lambda: divmod(c,b))

print("moddiv ", md)
print("divmod ", dm)




moddiv  5.806157339000492

divmod  4.322451676005585

divmod is faster. divmod 更快。

Patching as well Ralph Bolton's answer .修补以及拉尔夫博尔顿的回答 Moving to a class and moving tulp of tulp (intervals) to dictionary.移动到一个类并将 tulp 的 tulp(间隔)移动到字典。 Adding an optional rounded function depending of granularity (enable by default).根据粒度添加可选的舍入函数(默认启用)。 Ready to translation using gettext (default is disable).准备使用 gettext 进行翻译(默认为禁用)。 This is intend to be load from an module.这是打算从模块加载的。 This is for python3 (tested 3.6 - 3.8)这适用于 python3(测试 3.6 - 3.8)

import gettext
import locale
from itertools import chain

mylocale = locale.getdefaultlocale()
# see --> https://stackoverflow.com/a/10174657/11869956 thx 
#localedir = os.path.join(os.path.dirname(__file__), 'locales')
# or python > 3.4:
try:
    localedir = pathlib.Path(__file__).parent/'locales'
    lang_translations = gettext.translation('utils', localedir, 
                                            languages=[mylocale[0]])
    lang_translations.install()
    _ = lang_translations.gettext
except Exception as exc:
    print('Error: unexcept error while initializing translation:', file=sys.stderr)
    print(f'Error: {exc}', file=sys.stderr)
    print(f'Error: localedir={localedir}, languages={mylocale[0]}', file=sys.stderr)
    print('Error: translation has been disabled.', file=sys.stderr)
    _ = gettext.gettext

Here is the class:这是课程:

class FormatTimestamp:
    """Convert seconds to, optional rounded, time depending of granularity's degrees.
        inspired by https://stackoverflow.com/a/24542445/11869956"""
    def __init__(self):
        # For now i haven't found a way to do it better
        # TODO: optimize ?!? ;)
        self.intervals = {
            # 'years'     :   31556952,  # https://www.calculateme.com/time/years/to-seconds/
            # https://www.calculateme.com/time/months/to-seconds/ -> 2629746 seconds
            # But it's outputing some strange result :
            # So 3 seconds less (2629743) : 4 weeks, 2 days, 10 hours, 29 minutes and 3 seconds
            # than after 3 more seconds : 1 month ?!?
            # Google give me 2628000 seconds
            # So 3 seconds less (2627997): 4 weeks, 2 days, 9 hours, 59 minutes and 57 seconds
            # Strange as well 
            # So for the moment latest is week ...
            #'months'    :   2419200, # 60 * 60 * 24 * 7 * 4 
            'weeks'     :   604800,  # 60 * 60 * 24 * 7
            'days'      :   86400,    # 60 * 60 * 24
            'hours'     :   3600,    # 60 * 60
            'minutes'   :   60,
            'seconds'  :   1
            }
        self.nextkey = {
            'seconds'   :   'minutes',
            'minutes'   :   'hours',
            'hours'     :   'days',
            'days'      :   'weeks',
            'weeks'     :   'weeks',
            #'months'    :   'months',
            #'years'     :   'years' # stop here
            }
        self.translate = {
            'weeks'     :   _('weeks'),
            'days'      :   _('days'),
            'hours'     :   _('hours'),
            'minutes'   :   _('minutes'),
            'seconds'   :   _('seconds'),
            ## Single
            'week'      :   _('week'),
            'day'       :   _('day'),
            'hour'      :   _('hour'),
            'minute'    :   _('minute'),
            'second'    :   _('second'),
            ' and'      :   _('and'),
            ','         :   _(','),     # This is for compatibility
            ''          :   '\0'        # same here BUT we CANNOT pass empty string to gettext 
                                        # or we get : warning: Empty msgid.  It is reserved by GNU gettext:
                                        # gettext("") returns the header entry with
                                        # meta information, not the empty string.
                                        # Thx to --> https://stackoverflow.com/a/30852705/11869956 - saved my day
            }

    def convert(self, seconds, granularity=2, rounded=True, translate=False):
        """Proceed the conversion"""

        def _format(result):
            """Return the formatted result
            TODO : numpy / google docstrings"""
            start = 1 
            length = len(result)
            none = 0
            next_item = False
            for item in reversed(result[:]):
                if item['value']:
                    # if we have more than one item
                    if length - none > 1:
                        # This is the first 'real' item 
                        if start == 1:
                            item['punctuation'] = ''
                            next_item = True
                        elif next_item:
                            # This is the second 'real' item
                            # Happened 'and' to key name
                            item['punctuation'] = ' and'
                            next_item = False
                        # If there is more than two 'real' item
                        # than happened ','
                        elif 2 < start:
                            item['punctuation'] = ','
                        else:
                            item['punctuation'] = ''
                    else:
                        item['punctuation'] = ''
                    start += 1
                else:
                    none += 1
            return [ { 'value'        :   mydict['value'], 
                       'name'         :   mydict['name_strip'],
                       'punctuation'  :   mydict['punctuation'] } for mydict in result \
                                                                  if mydict['value'] is not None ]


        def _rstrip(value, name):
            """Rstrip 's' name depending of value"""
            if value == 1:
                name = name.rstrip('s')
            return name


        # Make sure granularity is an integer
        if not isinstance(granularity, int):
            raise ValueError(f'Granularity should be an integer: {granularity}')

        # For seconds only don't need to compute
        if seconds < 0:
            return 'any time now.'
        elif seconds < 60:
            return 'less than a minute.'

        result = []
        for name, count in self.intervals.items():
            value = seconds // count
            if value:
                seconds -= value * count
                name_strip = _rstrip(value, name)
                # save as dict: value, name_strip (eventually strip), name (for reference), value in seconds
                # and count (for reference)
                result.append({ 
                        'value'        :   value,
                        'name_strip'   :   name_strip,
                        'name'         :   name, 
                        'seconds'      :   value * count,
                        'count'        :   count
                                 })
            else:
                if len(result) > 0:
                    # We strip the name as second == 0
                    name_strip = name.rstrip('s')
                    # adding None to key 'value' but keep other value
                    # in case when need to add seconds when we will 
                    # recompute every thing
                    result.append({ 
                        'value'        :   None,
                        'name_strip'   :   name_strip,
                        'name'         :   name, 
                        'seconds'      :   0,
                        'count'        :   count
                                 })

        # Get the length of the list
        length = len(result)
        # Don't need to compute everything / every time
        if length < granularity or not rounded:
            if translate:
                return ' '.join('{0} {1}{2}'.format(item['value'], _(self.translate[item['name']]), 
                                                _(self.translate[item['punctuation']])) \
                                                for item in _format(result))
            else:
                return ' '.join('{0} {1}{2}'.format(item['value'], item['name'], item['punctuation']) \
                                                for item in _format(result))

        start = length - 1
        # Reverse list so the firsts elements 
        # could be not selected depending on granularity.
        # And we can delete item after we had his seconds to next
        # item in the current list (result)
        for item in reversed(result[:]):
            if granularity <= start <= length - 1:
                # So we have to round
                current_index = result.index(item)
                next_index = current_index - 1
                # skip item value == None
                # if the seconds of current item is superior
                # to the half seconds of the next item: round
                if item['value'] and item['seconds'] > result[next_index]['count'] // 2:
                    # +1 to the next item (in seconds: depending on item count)
                    result[next_index]['seconds'] += result[next_index]['count']
                # Remove item which is not selected
                del result[current_index]
            start -= 1
        # Ok now recalculate everything
        # Reverse as well 
        for item in reversed(result[:]):
            # Check if seconds is superior or equal to the next item 
            # but not from 'result' list but from 'self.intervals' dict
            # Make sure it's not None
            if item['value']:
                next_item_name = self.nextkey[item['name']]
                # This mean we are at weeks
                if item['name'] == next_item_name:
                    # Just recalcul
                    item['value'] = item['seconds'] // item['count']
                    item['name_strip'] = _rstrip(item['value'], item['name'])
                # Stop to weeks to stay 'right' 
                elif item['seconds'] >= self.intervals[next_item_name]:
                    # First make sure we have the 'next item'
                    # found via --> https://stackoverflow.com/q/26447309/11869956
                    # maybe there is a faster way to do it ? - TODO
                    if any(search_item['name'] == next_item_name for search_item in result):
                        next_item_index = result.index(item) - 1
                        # Append to
                        result[next_item_index]['seconds'] += item['seconds']
                        # recalculate value
                        result[next_item_index]['value'] = result[next_item_index]['seconds'] // \
                                                           result[next_item_index]['count']
                        # strip or not
                        result[next_item_index]['name_strip'] = _rstrip(result[next_item_index]['value'],
                                                                       result[next_item_index]['name'])
                    else:
                        # Creating 
                        next_item_index = result.index(item) - 1
                        # get count
                        next_item_count = self.intervals[next_item_name]
                        # convert seconds
                        next_item_value = item['seconds'] // next_item_count
                        # strip 's' or not
                        next_item_name_strip = _rstrip(next_item_value, next_item_name)
                        # added to dict
                        next_item = {
                                       'value'      :   next_item_value,
                                       'name_strip' :   next_item_name_strip,
                                       'name'       :   next_item_name,
                                       'seconds'    :   item['seconds'],
                                       'count'      :   next_item_count
                                       }
                        # insert to the list
                        result.insert(next_item_index, next_item)
                    # Remove current item
                    del result[result.index(item)]
                else:
                    # for current item recalculate
                    # keys 'value' and 'name_strip'
                    item['value'] = item['seconds'] // item['count']
                    item['name_strip'] = _rstrip(item['value'], item['name'])
        if translate:
            return ' '.join('{0} {1}{2}'.format(item['value'], 
                                                _(self.translate[item['name']]), 
                                                _(self.translate[item['punctuation']])) \
                                                for item in _format(result))
        else:
            return ' '.join('{0} {1}{2}'.format(item['value'], item['name'], item['punctuation']) \
                                                for item in _format(result))

To use it:要使用它:

myformater = FormatTimestamp()
myconverter = myformater.convert(seconds) 

granularity = 1 - 5, rounded = True / False, translate = True / False粒度 = 1 - 5,四舍五入 = True / False,平移 = True / False

Some test to show difference:一些测试以显示差异:

myformater = FormatTimestamp()
for firstrange in [131440, 563440, 604780, 2419180, 113478160]:
    print(f'#### Seconds : {firstrange} ####')
    print('\tFull - function: {0}'.format(display_time(firstrange, granularity=5)))
    print('\tFull -    class: {0}'.format(myformater.convert(firstrange, granularity=5))) 
    for secondrange in range(1, 6, 1):
        print('\tGranularity   this   answer ({0}): {1}'.format(secondrange, 
                                                             myformater.convert(firstrange,
                                                                                granularity=secondrange, translate=False)))
        print('\tGranularity Bolton\'s answer ({0}): {1}'.format(secondrange, display_time(firstrange,
                                                                                granularity=secondrange)))
    print()
Seconds : 131440 秒数:131440
 Full - function: 1 day, 12 hours, 30 minutes, 40 seconds Full - class: 1 day, 12 hours, 30 minutes and 40 seconds Granularity this answer (1): 2 days Granularity Bolton's answer (1): 1 day Granularity this answer (2): 1 day and 13 hours Granularity Bolton's answer (2): 1 day, 12 hours Granularity this answer (3): 1 day, 12 hours and 31 minutes Granularity Bolton's answer (3): 1 day, 12 hours, 30 minutes Granularity this answer (4): 1 day, 12 hours, 30 minutes and 40 seconds Granularity Bolton's answer (4): 1 day, 12 hours, 30 minutes, 40 seconds Granularity this answer (5): 1 day, 12 hours, 30 minutes and 40 seconds Granularity Bolton's answer (5): 1 day, 12 hours, 30 minutes, 40 seconds
Seconds : 563440 秒数:563440
    Full - function: 3 weeks, 6 days, 23 hours, 59 minutes, 40 seconds
    Full -    class: 3 weeks, 6 days, 23 hours, 59 minutes and 40 seconds
    Granularity   this   answer (1): 4 weeks
    Granularity Bolton's answer (1): 3 weeks
    Granularity   this   answer (2): 4 weeks
    Granularity Bolton's answer (2): 3 weeks, 6 days
    Granularity   this   answer (3): 4 weeks
    Granularity Bolton's answer (3): 3 weeks, 6 days, 23 hours
    Granularity   this   answer (4): 4 weeks
    Granularity Bolton's answer (4): 3 weeks, 6 days, 23 hours, 59 minutes
    Granularity   this   answer (5): 3 weeks, 6 days, 23 hours, 59 minutes and 40 seconds
    Granularity Bolton's answer (5): 3 weeks, 6 days, 23 hours, 59 minutes, 40 seconds
Seconds : 604780 秒数:604780
 Full - function: 6 days, 23 hours, 59 minutes, 40 seconds Full - class: 6 days, 23 hours, 59 minutes and 40 seconds Granularity this answer (1): 1 week Granularity Bolton's answer (1): 6 days Granularity this answer (2): 1 week Granularity Bolton's answer (2): 6 days, 23 hours Granularity this answer (3): 1 week Granularity Bolton's answer (3): 6 days, 23 hours, 59 minutes Granularity this answer (4): 6 days, 23 hours, 59 minutes and 40 seconds Granularity Bolton's answer (4): 6 days, 23 hours, 59 minutes, 40 seconds Granularity this answer (5): 6 days, 23 hours, 59 minutes and 40 seconds Granularity Bolton's answer (5): 6 days, 23 hours, 59 minutes, 40 seconds
Seconds : 2419180 秒数:2419180
 Full - function: 3 weeks, 6 days, 23 hours, 59 minutes, 40 seconds Full - class: 3 weeks, 6 days, 23 hours, 59 minutes and 40 seconds Granularity this answer (1): 4 weeks Granularity Bolton's answer (1): 3 weeks Granularity this answer (2): 4 weeks Granularity Bolton's answer (2): 3 weeks, 6 days Granularity this answer (3): 4 weeks Granularity Bolton's answer (3): 3 weeks, 6 days, 23 hours Granularity this answer (4): 4 weeks Granularity Bolton's answer (4): 3 weeks, 6 days, 23 hours, 59 minutes Granularity this answer (5): 3 weeks, 6 days, 23 hours, 59 minutes and 40 seconds Granularity Bolton's answer (5): 3 weeks, 6 days, 23 hours, 59 minutes, 40 seconds
Seconds : 113478160 秒:113478160
 Full - function: 187 weeks, 4 days, 9 hours, 42 minutes, 40 seconds Full - class: 187 weeks, 4 days, 9 hours, 42 minutes and 40 seconds Granularity this answer (1): 188 weeks Granularity Bolton's answer (1): 187 weeks Granularity this answer (2): 187 weeks and 4 days Granularity Bolton's answer (2): 187 weeks, 4 days Granularity this answer (3): 187 weeks, 4 days and 10 hours Granularity Bolton's answer (3): 187 weeks, 4 days, 9 hours Granularity this answer (4): 187 weeks, 4 days, 9 hours and 43 minutes Granularity Bolton's answer (4): 187 weeks, 4 days, 9 hours, 42 minutes Granularity this answer (5): 187 weeks, 4 days, 9 hours, 42 minutes and 40 seconds Granularity Bolton's answer (5): 187 weeks, 4 days, 9 hours, 42 minutes, 40 seconds

I have a french translation ready.我准备好了法语翻译。 But it's fast to do the translation ... just few words.但是翻译速度很快……就几个字。 Hope this could help as the other answer help me a lot.希望这会有所帮助,因为其他答案对我有很大帮助。

This is like Bolton 's answer but with a few additions...这就像Bolton的答案,但有一些补充......

  • stored ratios in a dictionary instead of a tuple for better readability.将比率存储在字典而不是元组中以提高可读性。
  • added an if check for 0 seconds input.添加了一个 if 检查0秒输入。
  • added an if check to change the last , with and for complete grammar.添加了一个 if 检查来更改最后一个, with and以获得完整的语法。
def secondsToText(unit, granularity = 2):

  ratios = {
    'decades' : 311040000, # 60 * 60 * 24 * 30 * 12 * 10
    'years'   : 31104000,  # 60 * 60 * 24 * 30 * 12
    'months'  : 2592000,   # 60 * 60 * 24 * 30
    'days'    : 86400,     # 60 * 60 * 24
    'hours'   : 3600,      # 60 * 60
    'minutes' : 60,        # 60
    'seconds' : 1          # 1
  }

  texts = []
  for ratio in ratios:
    result, unit = divmod(unit, ratios[ratio])
    if result:
      if result == 1:
        ratio = ratio.rstrip('s')
      texts.append(f'{result} {ratio}')
  texts = texts[:granularity] 
  if not texts:
    return f'0 {list(ratios)[-1]}'
  text = ', '.join(texts)
  if len(texts) > 1:
    index = text.rfind(',')
    text = f'{text[:index]} and {text[index + 1:]}'
  return text

Python 3 solution Python 3 解决方案

def seconds_to_dhms(total_seconds: int) -> str:
    seconds = total_seconds % 60
    total_minutes = total_seconds // 60
    total_hours = total_minutes // 60
    minutes = total_minutes % 60
    days = total_hours // 24
    hours = total_hours % 24
    return f"{days} days and {hours} hour and {minutes} minutes and {seconds} seconds."

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM