python - example - integerfield django
Python: convertir segundos a hh: mm: ss (10)
¿Has leído sobre el módulo de datetime ?
Editar / actualizar: la respuesta de SilentGhost tiene los detalles que mi respuesta deja fuera. Si te gusta esta respuesta, haz +1 también (o en su lugar). Repostado aquí:
>>> a = datetime.timedelta(seconds=65)
datetime.timedelta(0, 65)
>>> str(a)
''0:01:05''
Esta pregunta ya tiene una respuesta aquí:
Por favor, cómo convertir un int (número a segundos) a estos formatos: mm: ss o hh: mm: ss ?
Necesito hacer esto con el código de Python (y si es posible en una plantilla de Django?).
Muchas gracias ;-)
Además del hecho de que Python ha incorporado soporte para fechas y horas (ver la respuesta de Bigmattyh), encontrar minutos u horas a partir de segundos es fácil:
minutes = seconds / 60
hours = minutes / 60
Ahora, cuando quiera mostrar minutos o segundos, modifíquelos en 60 para que no sean más grandes que 59
Código que hace lo que se solicitó, con ejemplos, y que muestra cómo se manejan los casos que no especificó:
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"
Puede - y probablemente debería - almacenar esto como un timedelta en lugar de un int, pero eso es un problema aparte y timedelta en realidad no facilita esta tarea en particular.
No es una persona de Python pero es más fácil sin ninguna biblioteca:
total = 3800
seconds = total % 60
total = total - seconds
hours = total / 3600
total = total - (hours * 3600)
mins = total / 60
Código actualizado, gracias sth
No puedo creer que ninguna de las muchas respuestas ofrezca lo que consideraría como "la forma más obvia de hacerlo" (¡y ni siquiera soy holandés ...!) - hasta poco menos de 24 horas segundos (86399 segundos, específicamente):
>>> import time
>>> time.strftime(''%H:%M:%S'', time.gmtime(12345))
''03:25:45''
Hacerlo en una plantilla de Django es más quisquilloso, ya que el filtro de time
admite una sintaxis de formato de tiempo funky (inspirada, creo, de PHP) y también necesita el módulo datetime y una implementación de zona horaria como pytz para preparar los datos. Por ejemplo:
>>> 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''
Dependiendo de sus necesidades exactas, podría ser más conveniente definir un filtro personalizado para esta tarea de formateo en su aplicación.
Puede calcular la cantidad de minutos y horas a partir del número de segundos por división simple:
seconds = 12345
minutes = seconds // 60
hours = minutes // 60
print "%02d:%02d:%02d" % (hours, minutes % 60, seconds % 60)
print "%02d:%02d" % (minutes, seconds % 60)
Aquí //
es una división entera de pitones.
Si necesita hacer esto mucho, puede precalcular todas las cadenas posibles por el número de segundos en un día:
try:
from itertools import product
except ImportError:
def product(*seqs):
if len(seqs) == 2:
for s1 in seqs[0]:
for s2 in seqs[1]:
yield (s1,s2)
else:
for s in seqs[0]:
for p in product(*seqs[1:]):
yield (s,) + p
hhmmss = {}
i = 0
for (h,m,s) in product(range(24),range(60),range(60)):
hhmmss[i] = "%02d:%02d:%02d" % (h,m,s)
i += 1
Ahora la conversión de segundos para formatear cadena es una búsqueda dict rápida:
print hhmmss[12345]
huellas dactilares
''03:25:45''
Si usas divmod, eres inmune a los diferentes sabores de la división entera:
# 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:],
[(t*1000,),1000,60,60])
print secondsToStr(3800.123)
Huellas dactilares:
63:20
01:03:20
01:03:20.123
Solo tenga cuidado al dividir por 60: la división entre enteros devuelve un número entero -> 12/60 = 0 a menos que importe la división de futuros. Lo siguiente es copiar y pegar desde Python 2.6.2:
IDLE 2.6.2
>>> 12/60
0
>>> from __future__ import division
>>> 12/60
0.20000000000000001
>>> a = datetime.timedelta(seconds=65)
datetime.timedelta(0, 65)
>>> str(a)
''0:01:05''