Конвертировать timedelta в дни, часы и минуты

243

У меня есть таймделта. Я хочу дни, часы и минуты от этого - либо как кортеж, либо как словарь ... Я не смущен.

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

Мистер Фуз поднимает хорошую мысль.

Я имею дело с «списками» (немного похожими на списки на ebay), где у каждого есть продолжительность. Я пытаюсь найти оставшееся время, делаяwhen_added + duration - now

Правильно ли я сказал, что не будет учитывать DST? Если нет, то какой самый простой способ сложить / вычесть час?

Oli
источник
Если это просто для того, чтобы получить его в виде строки в формате ЧЧ: мм: сс, скажите «0:19:37» из timedeltaобъекта «datetime.timedelta (seconds = 1177)» : просто используйте str ()
Питер Мортенсен,

Ответы:

344

Если у вас есть datetime.timedeltaзначение td, td.daysуже дает вам «дней», которые вы хотите. timedeltaзначения сохраняют долю дня в секундах (а не в часах или минутах), поэтому вам действительно придется выполнять «тошнотворно простую математику», например:

def days_hours_minutes(td):
    return td.days, td.seconds//3600, (td.seconds//60)%60
Алекс Мартелли
источник
1
Имейте в виду, что, если tdотрицательно, -1 // 3600есть -1.
jcrs
4
Зачем // ? вместо /
Мохаммед Шариф С
10
//используется вместо /получения целого числа, а не с плавающей точкой. //является оператором деления на этаж: «деление, которое приводит к целому числу, отрегулированному влево в числовой строке», см. здесь .
Ээрик Свен Пуудист
1
@EerikSvenPuudist , как jcrsотмечалось, -1//3600является -1, так почему бы не использовать int(td.seconds/3600)вместо того, чтобы повернуть -1второй в 0часы , а не 1час назад?
simpleuser
а как насчет добавления оставшихся секунд? days, hours, minutes = x.days, x.seconds // 3600, x.seconds %3600//60а затем seconds = x.seconds - hours*3600 - minutes*60
Рафаэль
73

Это немного компактнее, вы получите часы, минуты и секунды в две строки.

days = td.days
hours, remainder = divmod(td.seconds, 3600)
minutes, seconds = divmod(remainder, 60)
# If you want to take into account fractions of a second
seconds += td.microseconds / 1e6
mberacochea
источник
7
это неверно, если td.daysне ноль. Вам нужно hours += td.days*24. Если вы хотите учитывать доли секунды (OP не делает); seconds += td.microseconds / 1e6может быть использован.
JFS
30
days, hours, minutes = td.days, td.seconds // 3600, td.seconds // 60 % 60

Что касается летнего времени, я думаю, что лучше всего конвертировать оба datetimeобъекта в секунды. Таким образом, система рассчитывает DST для вас.

>>> m13 = datetime(2010, 3, 13, 8, 0, 0)  # 2010 March 13 8:00 AM
>>> m14 = datetime(2010, 3, 14, 8, 0, 0)  # DST starts on this day, in my time zone
>>> mktime(m14.timetuple()) - mktime(m13.timetuple())     # difference in seconds
82800.0
>>> _/3600                                                # convert to hours
23.0
Джейсон Орендорфф
источник
1
mktime()может произойти сбой, если местный часовой пояс может иметь различное смещение utc в разное время (многие это делают) - вы можете использовать pytzмодуль для получения доступа к базе данных tz портативным детерминистическим способом. Кроме того, местное время может быть неоднозначным (50% вероятности ошибки) - вам нужна дополнительная информация для устранения неоднозначности, например, часто (не всегда) даты в файле журнала монотонны . См. Как я могу вычесть день из даты питона? что, возможно, придется иметь дело с аналогичными проблемами.
JFS
7

Я не понимаю

days, hours, minutes = td.days, td.seconds // 3600, td.seconds // 60 % 60

как насчет этого

days, hours, minutes = td.days, td.seconds // 3600, td.seconds % 3600 / 60.0

Вы получаете минуты и секунды минуты как поплавок.

Кемпбелл
источник
0

Я использовал следующее:

delta = timedelta()
totalMinute, second = divmod(delta.seconds, 60)
hour, minute = divmod(totalMinute, 60)
print(f"{hour}h{minute:02}m{second:02}s")
Матье КАРОФФ
источник
-3

Timedeltas имеют daysи secondsатрибут. Вы можете конвертировать их самостоятельно.

Йохен Ритцель
источник