Tengo una fecha de inicio como esta:
from django.utils.timezone import utc import datetime start_date = datetime.datetime.utcnow().replace(tzinfo=utc) end_date = datetime.datetime.utcnow().replace(tzinfo=utc) duration = end_date - start_date
Me sale de esta manera:
datetime.timedelta(0, 5, 41038)
¿Cómo convierto esto en tiempo normal como el siguiente?
10 minutos, 1 hora como esta
No hay un formateador timedelta
para los objetos timedelta
, pero es muy fácil hacerlo usted mismo:
days, seconds = duration.days, duration.seconds hours = days * 24 + seconds // 3600 minutes = (seconds % 3600) // 60 seconds = seconds % 60
O, de manera equivalente, si estás en Python 2.7+ o 3.2+:
seconds = duration.total_seconds() hours = seconds // 3600 minutes = (seconds % 3600) // 60 seconds = seconds % 60
Ahora puedes imprimirlo como quieras:
'{} minutes, {} hours'.format(minutes, hours)
Por ejemplo:
def convert_timedelta(duration): days, seconds = duration.days, duration.seconds hours = days * 24 + seconds // 3600 minutes = (seconds % 3600) // 60 seconds = (seconds % 60) return hours, minutes, seconds td = datetime.timedelta(2, 7743, 12345) hours, minutes, seconds = convert_timedelta(td) print '{} minutes, {} hours'.format(minutes, hours)
Esto imprimirá:
9 minutes, 50 hours
Si desea obtener “10 minutos, 1 hora” en lugar de “10 minutos, 1 horas”, también debe hacerlo manualmente:
print '{} minute{}, {} hour{}'.format(minutes, 's' if minutes != 1 else '', hours, 's' if minutes != 1 else '')
O tal vez desee escribir una función de english_plural
para hacer los bits de 's'
por usted, en lugar de repetirlo usted mismo.
De tus comentarios, parece que realmente quieres mantener los días separados. Eso es aún más fácil:
def convert_timedelta(duration): days, seconds = duration.days, duration.seconds hours = seconds // 3600 minutes = (seconds % 3600) // 60 seconds = (seconds % 60) return days, hours, minutes, seconds
Si desea convertir esto en un solo valor para almacenar en una base de datos, entonces vuelva a convertir ese valor único para formatearlo, haga lo siguiente:
def dhms_to_seconds(days, hours, minutes, seconds): return (((days * 24) + hours) * 60 + minutes) * 60 + seconds def seconds_to_dhms(seconds): days = seconds // (3600 * 24) hours = (seconds // 3600) % 24 minutes = (seconds // 60) % 60 seconds = seconds % 60 return days, hours, minutes, seconds
Así que, juntándolo:
def store_timedelta_in_database(thingy, duration): seconds = dhms_to_seconds(*convert_timedelta(duration)) db.execute('INSERT INTO foo (thingy, duration) VALUES (?, ?)', thingy, seconds) db.commit() def print_timedelta_from_database(thingy): cur = db.execute('SELECT duration FROM foo WHERE thingy = ?', thingy) seconds = int(cur.fetchone()[0]) days, hours, minutes, seconds = seconds_to_dhms(seconds) print '{} took {} minutes, {} hours, {} days'.format(thingy, minutes, hours, days)
A datetime.timedelta
corresponde a la diferencia entre dos fechas, no una fecha en sí. Solo se expresa en términos de días, segundos y microsegundos, ya que las unidades de tiempo más grandes, como meses y años, no se descomponen limpiamente (¿son 30 días 1 mes o 0,9677 meses?).
Si desea convertir un timedelta
en horas y minutos, puede usar el método total_seconds()
para obtener el número total de segundos y luego hacer algunos cálculos matemáticos:
x = datetime.timedelta(1, 5, 41038) # Interval of 1 day and 5.41038 seconds secs = x.total_seconds() hours = int(secs / 3600) minutes = int(secs / 60) % 60
No hay necesidad de funciones de ayuda personalizadas si todo lo que necesitamos es imprimir la cadena con el formato [D day[s], ][H]H:MM:SS[.UUUUUU]
. El objeto timedelta admite la operación str()
que hará esto. Funciona incluso en Python 2.6.
>>> from datetime import timedelta >>> timedelta(seconds=90136) datetime.timedelta(1, 3736) >>> str(timedelta(seconds=90136)) '1 day, 1:02:16'
Solo usa strftime 🙂
Algo como eso:
my_date = datetime.datetime(2013, 1, 7, 10, 31, 34, 243366, tzinfo=) print(my_date.strftime("%Y, %d %B"))
Después de editar su pregunta para dar formato a timedelta
, puede usar:
def timedelta_tuple(timedelta_object): return timedelta_object.days, timedelta_object.seconds//3600, (timedelta_object.seconds//60)%60
Definí la función de ayuda propia para convertir el objeto timedelta al formato ‘HH: MM: SS’, solo horas, minutos y segundos, sin cambiar las horas a días.
def format_timedelta(td): hours, remainder = divmod(td.total_seconds(), 3600) minutes, seconds = divmod(remainder, 60) hours, minutes, seconds = int(hours), int(minutes), int(seconds) if hours < 10: hours = '0%s' % int(hours) if minutes < 10: minutes = '0%s' % minutes if seconds < 10: seconds = '0%s' % seconds return '%s:%s:%s' % (hours, minutes, seconds)
¿Quieres imprimir la fecha en ese formato? Esta es la documentación de Python: http://docs.python.org/2/library/datetime.html#strftime-strptime-behavior
>>> a = datetime.datetime(2013, 1, 7, 10, 31, 34, 243366) >>> print a.strftime('%Y %d %B, %M:%S%p') >>> 2013 07 January, 31:34AM
Para el timedelta:
>>> a = datetime.timedelta(0,5,41038) >>> print '%s seconds, %s microseconds' % (a.seconds, a.microseconds)
Pero tenga en cuenta que debe asegurarse de que tenga el valor relacionado. Para los casos anteriores, no tiene los valores de horas y minutos, y debe calcular a partir de los segundos.
No creo que sea una buena idea cacarse.
Si solo desea una salida bonita, conviértala en str
con la función str()
o print()
directamente.
Y si hay un uso adicional de las horas y los minutos, puede analizarlo al uso del objeto datetime.strptime()
(y extraer la parte de tiempo con datetime.time()
mehtod), por ejemplo:
import datetime delta = datetime.timedelta(seconds=10000) time_obj = datetime.datetime.strptime(str(delta),'%H:%M:%S').time()
datetime.timedelta(hours=1, minutes=10) #python 2.7