如何在 Python 中将 datetime.timedelta 转换为分钟、小时?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14190045/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 10:43:12  来源:igfitidea点击:

How do I convert datetime.timedelta to minutes, hours in Python?

pythondjango

提问by user1881957

I get a start_date like this:

我得到这样的 start_date:

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

I get output like this:

我得到这样的输出:

datetime.timedelta(0, 5, 41038)

How do I convert this into normal time like the following?

如何将其转换为正常时间,如下所示?

10 minutes, 1 hour like this

10分钟,1小时这样

采纳答案by abarnert

There's no built-in formatter for timedeltaobjects, but it's pretty easy to do it yourself:

没有用于timedelta对象的内置格式化程序,但自己很容易做到:

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

Or, equivalently, if you're in Python 2.7+ or 3.2+:

或者,等效地,如果您使用的是 Python 2.7+ 或 3.2+:

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

Now you can print it however you want:

现在您可以随心所欲地打印它:

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

For example:

例如:

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)

This will print:

这将打印:

9 minutes, 50 hours

If you want to get "10 minutes, 1 hour" instead of "10 minutes, 1 hours", you need to do that manually too:

如果您想获得“10 分钟 1 小时”而不是“10 分钟 1 小时”,您也需要手动执行此操作:

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

Or you may want to write an english_pluralfunction to do the 's'bits for you, instead of repeating yourself.

或者您可能想编写一个english_plural函数来's'为您完成这些工作,而不是重复自己。

From your comments, it sounds like you actually want to keep the days separate. That's even easier:

从你的评论来看,听起来你真的想把日子分开。这更容易:

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

If you want to convert this to a single value to store in a database, then convert that single value back to format it, do this:

如果要将其转换为单个值以存储在数据库中,然后将该单个值转换回以对其进行格式化,请执行以下操作:

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

So, putting it together:

所以,把它放在一起:

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)

回答by jinghli

Do you want to print the date in that format? This is the Python documentation: http://docs.python.org/2/library/datetime.html#strftime-strptime-behavior

您想以这种格式打印日期吗?这是 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

For the timedelta:

对于时间增量:

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

But please notice, you should make sure it has the related value. For the above cases, it doesn't have the hours and minute values, and you should calculate from the seconds.

但请注意,您应该确保它具有相关值。对于上述情况,它没有小时和分钟值,您应该从秒计算。

回答by Infinity

Just use strftime:)

只需使用strftime:)

Something like that:

类似的东西:

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


After edited your question to format timedelta, you could use:

将您的问题编辑为 format 后timedelta,您可以使用:

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

回答by Adam Rosenfield

A datetime.timedeltacorresponds to the differencebetween two dates, not a date itself. It's only expressed in terms of days, seconds, and microseconds, since larger time units like months and years don't decompose cleanly (is 30 days 1 month or 0.9677 months?).

Adatetime.timedelta对应于两个日期之间的差异,而不是日期本身。它仅以天、秒和微秒表示,因为像月和年这样的较大时间单位不能完全分解(30 天是 1 个月还是 0.9677 个月?)。

If you want to convert a timedeltainto hours and minutes, you can use the total_seconds()method to get the total number of seconds and then do some math:

如果要将 a 转换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

回答by user5435345

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

回答by MobilePro.pl

I defined own helper function to convert timedelta object to 'HH:MM:SS' format - only hours, minutes and seconds, without changing hours to days.

我定义了自己的辅助函数来将 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)

回答by wombatonfire

There is no need for custom helper functions if all we need is to print the string of the form [D day[s], ][H]H:MM:SS[.UUUUUU]. timedeltaobject supports str()operation that will do this. It works even in Python 2.6.

如果我们只需要打印表单的字符串,则不需要自定义辅助函数[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'

回答by C.K.

I don't think it's a good idea to caculate yourself.

我认为计算自己不是一个好主意。

If you just want a pretty output, just covert it into strwith str()function or directly print()it.

如果您只想要一个漂亮的输出,只需将其转换strstr()函数或直接转换即可print()

And if there's further usage of the hours and minutes, you can parse it to datetimeobject use datetime.strptime()(and extract the time part with datetime.time()mehtod), for example:

如果还有小时和分钟的进一步使用,您可以将其解析为datetime对象使用datetime.strptime()(并使用datetime.time()mehtod提取时间部分),例如:

import datetime

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

回答by ingyhere

Another alternative for this (older) question:

这个(较旧的)问题的另一种选择:

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'

The above is a good way to tell if your current time zone is actually in daylight savings time or not. (It provides an offset of 0 or 1.) Anyway, the real work is being done by time.strftime("%H:%M:%S", time.gmtime(36901))which does work on the output of gmtime().

以上是判断您当前时区是否实际上处于夏令时的好方法。(它提供了 0 或 1 的偏移量。)无论如何,真正的工作是由time.strftime("%H:%M:%S", time.gmtime(36901))which 对 的输出进行工作来完成的gmtime()

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

And, that's it! (NOTE: Here's a link to format specifiers for time.strftime(). ...)

而且,就是这样!(注意:这是..格式说明符time.strftime()链接

回答by zzzz zzzz

# Try this code
from datetime import timedelta

class TimeDelta(timedelta):
    def __str__(self):
        _times = super(TimeDelta, self).__str__().split(':')
        if "," in _times[0]:
            _hour = int(_times[0].split(',')[-1].strip())
            if _hour:
                _times[0] += " hours" if _hour > 1 else " hour"
            else:
                _times[0] = _times[0].split(',')[0]
        else:
            _hour = int(_times[0].strip())
            if _hour:
                _times[0] += " hours" if _hour > 1 else " hour"
            else:
                _times[0] = ""
        _min = int(_times[1])
        if _min:
            _times[1] += " minutes" if _min > 1 else " minute"
        else:
            _times[1] = ""
        _sec = int(_times[2])
        if _sec:
            _times[2] += " seconds" if _sec > 1 else " second"
        else:
            _times[2] = ""
        return ", ".join([i for i in _times if i]).strip(" ,").title()

# Test
>>> str(TimeDelta(seconds=10))
'10 Seconds'
>>> str(TimeDelta(seconds=60))
'01 Minute'
>>> str(TimeDelta(seconds=90))
'01 Minute, 30 Seconds'
>>> str(TimeDelta(seconds=3000))
'50 Minutes'
>>> str(TimeDelta(seconds=3600))
'1 Hour'
>>> str(TimeDelta(seconds=3690))
'1 Hour, 01 Minute, 30 Seconds'
>>> str(TimeDelta(seconds=3660))
'1 Hour, 01 Minute'
>>> str(TimeDelta(seconds=3630))
'1 Hour, 30 Seconds'
>>> str(TimeDelta(seconds=3600*20))
'20 Hours'
>>> str(TimeDelta(seconds=3600*20 + 3000))
'20 Hours, 50 Minutes'
>>> str(TimeDelta(seconds=3600*20 + 3630))
'21 Hours, 30 Seconds'
>>> str(TimeDelta(seconds=3600*20 + 3660))
'21 Hours, 01 Minute'
>>> str(TimeDelta(seconds=3600*20 + 3690))
'21 Hours, 01 Minute, 30 Seconds'
>>> str(TimeDelta(seconds=3600*24))
'1 Day'
>>> str(TimeDelta(seconds=3600*24 + 10))
'1 Day, 10 Seconds'
>>> str(TimeDelta(seconds=3600*24 + 60))
'1 Day, 01 Minute'
>>> str(TimeDelta(seconds=3600*24 + 90))
'1 Day, 01 Minute, 30 Seconds'
>>> str(TimeDelta(seconds=3600*24 + 3000))
'1 Day, 50 Minutes'
>>> str(TimeDelta(seconds=3600*24 + 3600))
'1 Day, 1 Hour'
>>> str(TimeDelta(seconds=3600*24 + 3630))
'1 Day, 1 Hour, 30 Seconds'
>>> str(TimeDelta(seconds=3600*24 + 3660))
'1 Day, 1 Hour, 01 Minute'
>>> str(TimeDelta(seconds=3600*24 + 3690))
'1 Day, 1 Hour, 01 Minute, 30 Seconds'
>>> str(TimeDelta(seconds=3600*24*2))
'2 Days'
>>> str(TimeDelta(seconds=3600*24*2 + 9999))
'2 Days, 2 Hours, 46 Minutes, 39 Seconds'