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

Как мне конвертировать datetime.timedelta в минуты, часы в Python?

Я получаю начальную дату как это:

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

Я получаю вывод, как это:

datetime.timedelta(0, 5, 41038)

Как мне преобразовать это в обычное время, как показано ниже?

10 минут, 1 час, как это

4b9b3361

Ответ 1

Нет встроенного форматирования для объектов timedelta, но это довольно легко сделать сами:

days, seconds = duration.days, duration.seconds
hours = days * 24 + seconds // 3600
minutes = (seconds % 3600) // 60
seconds = seconds % 60

Или, эквивалентно, если вы находитесь в Python версии 2.7+ или 3.2 +:

seconds = duration.total_seconds()
hours = seconds // 3600
minutes = (seconds % 3600) // 60
seconds = seconds % 60

Теперь вы можете распечатать его, как хотите:

'{} minutes, {} hours'.format(minutes, hours)

Например:

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)

Это напечатает:

9 minutes, 50 hours

Если вы хотите получить "10 минут, 1 час" вместо "10 минут, 1 час", вам также нужно сделать это вручную:

print '{} minute{}, {} hour{}'.format(minutes, 's' if minutes != 1 else '',
                                      hours, 's' if minutes != 1 else '')

Или вы можете написать функцию english_plural для выполнения бит 's' для вас, а не повторять себя.

Из ваших комментариев это звучит так, будто вы действительно хотите, чтобы дни были раздельными. Это еще проще:

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

Если вы хотите преобразовать это в одно значение для хранения в базе данных, затем преобразуйте это единственное значение обратно для его форматирования, сделайте следующее:

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

Итак, соединяясь:

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)

Ответ 2

A datetime.timedelta соответствует разнице между двумя датами, а не самой датой. Это выражается только в терминах дней, секунд и микросекунд, так как более крупные единицы времени, такие как месяцы и годы, не разлагаются чисто (30 дней 1 месяц или 0,9677 месяца?).

Если вы хотите преобразовать timedelta в часы и минуты, вы можете использовать метод total_seconds(), чтобы получить общее количество секунд, а затем выполните некоторую математику:

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

Ответ 3

Там нет необходимости для пользовательских вспомогательных функций, если все, что нам нужно, это напечатать строку формы [D day[s], ][H]H:MM:SS[.UUUUUU]. Объект timedelta поддерживает операцию str(), которая сделает это. Это работает даже в Python 2.6.

>>> from datetime import timedelta
>>> timedelta(seconds=90136)
datetime.timedelta(1, 3736)
>>> str(timedelta(seconds=90136))
'1 day, 1:02:16'

Ответ 4

Просто используйте strftime:)

Что-то вроде этого:

my_date = datetime.datetime(2013, 1, 7, 10, 31, 34, 243366, tzinfo=<UTC>)
print(my_date.strftime("%Y, %d %B"))

После редактирования вашего вопроса в формате timedelta вы можете использовать:

def timedelta_tuple(timedelta_object):
   return timedelta_object.days, timedelta_object.seconds//3600, (timedelta_object.seconds//60)%60

Ответ 5

Я не думаю, что это хорошая идея, чтобы успокоиться.

Если вы хотите получить симпатичный вывод, просто преобразуйте его в str с помощью функции str() или непосредственно print().

И если в дальнейшем используются часы и минуты, вы можете проанализировать их для объекта datetime, используя datetime.strptime() (и извлечь часть времени с помощью метода datetime.time()), например:

import datetime

delta = datetime.timedelta(seconds=10000)
time_obj = datetime.datetime.strptime(str(delta),'%H:%M:%S').time()

Ответ 6

Я определил собственную вспомогательную функцию для преобразования объекта timedelta в формат "HH: MM: SS" - только часы, минуты и секунды, без изменения часов до нескольких дней.

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)

Ответ 7

Вы хотите напечатать дату в этом формате? Это документация по 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

Для временной шкалы:

>>> a =  datetime.timedelta(0,5,41038)
>>> print '%s seconds, %s microseconds' % (a.seconds, a.microseconds)

Но, пожалуйста, обратите внимание, вы должны убедиться, что он имеет соответствующее значение. Для вышеупомянутых случаев у него нет значений часов и минут, и вы должны рассчитать их по секундам.

Ответ 8

Еще один вариант ответа на этот (более старый) вопрос:

import datetime
import pytz
import time

pacific=pytz.timezone('US/Pacific')
now=datetime.datetime.now()
# pacific.dst(now).total_seconds() yields 3600 secs. [aka 1 hour]
time.strftime("%-H", time.gmtime(pacific.dst(now).total_seconds()))
'1'

Вышесказанное - хороший способ узнать, действительно ли ваш текущий часовой пояс находится в летнее время или нет. (Он обеспечивает смещение 0 или 1.) В любом случае, настоящая работа выполняется time.strftime("%H:%M:%S", time.gmtime(36901)), который работает с выходом gmtime().

>>> time.strftime("%H:%M:%S",time.gmtime(36901))  # secs = 36901
'10:15:01'

И это все! (ПРИМЕЧАНИЕ: здесь ссылка на спецификаторы формата для time.strftime()....)

Ответ 9

datetime.timedelta(hours=1, minutes=10)
#python 2.7