Подтвердить что ты не робот

Функция Python для преобразования секунд в минуты, часы и дни

Вопрос: Напишите программу, которая просит пользователя ввести несколько секунд, и работает следующим образом:

  • Есть 60 секунд в минуту. Если количество секунд, введенных пользователем, больше или равно 60, программа должна отображать количество минут за это несколько секунд.

  • Есть 3600 секунд в час. Если количество секунд, введенных пользователем, больше или равно 3600, программа должна отображать количество часов в течение многих секунд.

  • Есть 86400 секунд в день. Если количество секунд, введенных пользователем, больше или равно 86400, программа должна отображать количество дней в течение многих секунд.

Что я до сих пор:

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
4b9b3361

Ответ 1

Это преобразует n секунд в d дней, h часов, минут и секунд.

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

Ответ 2

Этот лакомый кусочек полезен для отображения прошедшего времени в разной степени детализации.

Я лично считаю, что вопросы эффективности здесь практически бессмысленны, пока что-то неэффективно не делается. Преждевременная оптимизация - корень довольно злого. Это достаточно быстро, что это никогда не будет вашим дросселем.

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

.. и это обеспечивает достойный вывод:

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'

Ответ 3

Чтобы преобразовать секунды (как строку) в дату и время, это также может помочь. Вы получаете количество дней и секунд. Секунды могут быть дополнительно преобразованы в минуты и часы.

from datetime import datetime, timedelta
sec = timedelta(seconds=(input('Enter the number of seconds: ')))
time = str(sec)

Ответ 4

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

Ответ 5

Я не совсем уверен, хочу ли вы этого, но у меня была аналогичная задача, и мне нужно было удалить поле, если оно равно нулю. Например, 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: несколько лучшая версия, которая обрабатывает плюрализацию слов.

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: создал gist, который делает это на нескольких языках

Ответ 6

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

Ответ 7

def convertSeconds(seconds):
    h = seconds//(60*60)
    m = (seconds-h*60*60)//60
    s = seconds-(h*60*60)-(m*60)
    return [h, m, s]

Ввод функции представляет собой количество секунд, а возвращаемое значение представляет собой список часов, минут и секунд, которые представляют это количество секунд.

Ответ 8

Делайте это наоборот, вычитая секунды по мере необходимости, и не называйте это временем; есть пакет с таким именем:

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

Ответ 9

На первый взгляд, я решил, что 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) )

Встроенная функция divmod кажется невероятно медленной по сравнению с использованием простого деления и модуля.

division and modulus: 12.5737669468
divmod function: 17.2861430645

Ответ 10

Эти функции довольно компактны и используют только стандартный 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))

И вот тесты, чтобы пойти с ними. Я использую пакет 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')

Ответ 11

Patching Mr.B answer (извините, недостаточно комментариев для комментариев), мы можем вернуть переменную детализацию в зависимости от количества времени. Например, мы не говорим "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])

Некорректный ввод:

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

... возвращает этот вывод:

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

Ответ 12

Ответ "timeit" выше, который объявляет, что divmod медленнее, имеет серьезно ошибочную логику.

Test1 вызывает операторов.

Test2 вызывает функцию divmod, а вызов функции имеет накладные расходы.

Более точный способ проверки будет:

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 быстрее.

Ответ 13

Хотя divmod() уже упоминался, я не увидел того, что я считаю хорошим примером. Вот мой:

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

Какие выводы:

11 days, 6 hours, 0 minutes, 21 seconds

Ответ 14

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)

Выход: введите количество секунд: 2434234232.

Результат: 28174 дня, 0 часов, 10 минут, 32 секунды

Ответ 15

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)