Перетворити тиммеделю на дні, години та хвилини


243

У мене є timedelta. Я хочу, щоб дні, години та хвилини від цього були - чи то кортежем, чи словником ... Мене не метушило.

Я, мабуть, робив це десяток разів на десятках мов протягом багатьох років, але Python, як правило, має просту відповідь на все, тому я думав, що я запитаю тут, перш ніж скинути якусь нудотно просту (але багатослівну) математику.

Містер Фооз підкреслює хорошу думку.

Я маю справу з "списками" (трохи схожими на листи на ebay), де кожен має тривалість. Я намагаюся знайти час, який залишився, роблячиwhen_added + duration - now

Я маю рацію, кажучи, що не враховував DST? Якщо ні, то який найпростіший спосіб додати / відняти годину?


Якщо це просто отримати його як рядок у форматі HH: mm: ss, скажіть "0:19:37" від timedeltaоб'єкта "datetime.timedelta (секунд = 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
чому //? замість /
Мохаммед Шаріф C

10
//використовується замість, /щоб отримати ціле число, а не поплавок. //є оператором поділу підлоги: "поділ, який призводить до цілого числа, відрегульованого зліва в рядку чисел", дивіться тут .
Eerik Sven Puudist

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

7
це неправильно, якщо td.daysвін не дорівнює нулю. Вам потрібно hours += td.days*24. Якщо ви хочете врахувати частки секунди (ОП не робить); seconds += td.microseconds / 1e6може бути використаний.
jfs

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

Що стосується DST, я думаю, що найкраще - перетворити обидва 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()може вийти з ладу, якщо локальний часовий пояс може мати різний зміщення 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")

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.