2010-10-29 41 views
16

Pregunta: escribir un programa que pide al usuario que introduzca un número de segundos, y funciona de la siguiente manera:función de Python para convertir segundos a minutos, horas y días

  • hay 60 segundos en una minuto. Si la cantidad de segundos ingresados ​​por el usuario es mayor o igual que 60, el programa debe mostrar la cantidad de minutos en esos segundos.

  • Hay 3.600 segundos en una hora. Si el número de segundos ingresados ​​por el usuario es mayor o igual que 3600, el programa debería mostrar el número de horas en esos segundos.

  • Hay 86.400 segundos en un día. Si la cantidad de segundos ingresados ​​por el usuario es mayor o igual a 86400, el programa debería mostrar la cantidad de días en esos segundos.

Lo que tengo hasta ahora:

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 
+0

Sugerencia: http://docs.python.org/library/functions.html#divmod le permite hacer algo como esto: 'divmod (3660,3600) # (1, 60)' y 'divmod (60 , 60) # (1,0) '. Además, ¿qué estás preguntando exactamente? –

+0

Escriba cómo lo haría en papel, luego conviértalo en código. –

+0

Según su descripción, sus declaraciones "if" deberían ser '> =', no '<='. –

Respuesta

1

hacerlo de la otra manera alrededor de restar los segundos, según sea necesario, y no lo llamamos el tiempo; hay un paquete con ese nombre:

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, ':', min, ':', sec 
+2

no acaba de cumplir los requisitos. –

29

Esto convertirá n segundos en d día, h horas, m minutos, y s segundos.

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

Creo que hay un máximo en segundos. Entonces esta no es la forma sugerida. Consulte la documentación: \t segundos entre 0 y 86399 incluido http://docs.python.org/library/datetime.html –

+2

Hay 86.400 segundos en un día, así que por eso sólo puede tener 0-86399 segundos. En otras palabras, timedelta (seconds = 86400) se resolvería en days = 1, seconds = 0. Por lo tanto, 86399 no es el valor máximo de entrada para segundos. –

+0

Parece que entendí mal la documentación, si es la forma en que dices. Entonces, ¿qué quiere decir es que si uso el siguiente timedelta: timedelta (seconds = 86450) se resolverá automáticamente con timedelta (days = 1, seconds = 50)? ¿Es eso correcto? Gracias por tu comentario. –

1

A primera vista, pensé DIVMOD sería más rápido, ya que es un solo estado y una función incorporada, pero timeit parece demostrar lo contrario. Considere este pequeño ejemplo que se me ocurrió cuando estaba tratando de averiguar el método más rápido para su uso en un bucle que se ejecuta continuamente en un gobject idle_add la división de un contador de segundos en un tiempo legible por humanos para la actualización de una etiqueta barra de progreso.

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

La función divmod incorporada parece increíblemente más lenta en comparación con el uso de la división simple y el módulo.

division and modulus: 12.5737669468 
divmod function: 17.2861430645 
21

Este dato es útil para mostrar el tiempo transcurrido a diversos grados de granularidad.

yo personalmente creo que las cuestiones de eficiencia son prácticamente de sentido aquí, tanto tiempo como algo muy ineficiente no se está haciendo. La optimización prematura es la raíz de bastante mal. Esto es lo suficientemente rápido como para que nunca sea tu punto de estrangulación.

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

..y esto proporciona una salida decente:

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' 
+1

En mi sistema Python 2.6.6, tuve que usar 'result.append ("% s% s "% (value, name))' –

1

Estas funciones son bastante compacto y sólo se utiliza el estándar de Python 2.6 y posterior.

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

Y estas son las pruebas para ir con ellas. Estoy usando el paquete pytest como una forma sencilla de probar excepciones.

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') 
0
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)) 
+4

No es bueno simplemente publicar el código como una respuesta. También debe incluir alguna explicación, incluso si cree que puede ser evidente. –

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

Convertir segundos (como cadena) en fecha y hora, esto también podría ayudar. Obtienes el número de días y segundos. Los segundos se pueden convertir en minutos y horas.

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

No estoy del todo seguro si lo desea, pero tuve una tarea similar y necesitaba eliminar un campo si es cero. Por ejemplo, 86401 segundos mostrarían "1 día, 1 segundo" en lugar de "1 día, 0 horas, 0 minutos, 1 segundo". El siguiente código hace eso.

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 

EDITAR: una versión ligeramente mejor que maneja la pluralización de palabras.

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: (. Lo sentimos, pero no lo suficiente como representante de comentar) creado un gist que hace que en varios idiomas

0

parches Mr.B's answer, podemos volver granularidad variable en función de la cantidad de tiempo. Por ejemplo, no decimos "de 1 semana, 5 segundos", que acaba de decir "1 week":

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

Algunos de entrada de ejemplo:

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

... devuelve esta salida:

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 
Cuestiones relacionadas