Định dạng timedelta thành chuỗi


275

Tôi gặp sự cố khi định dạng một datetime.timedeltađối tượng.

Đây là những gì tôi đang cố gắng thực hiện: Tôi có một danh sách các đối tượng và một trong các thành viên của lớp đối tượng là một đối tượng timedelta hiển thị thời lượng của một sự kiện. Tôi muốn hiển thị thời lượng đó theo định dạng giờ: phút.

Tôi đã thử nhiều phương pháp để làm việc này và tôi gặp khó khăn. Cách tiếp cận hiện tại của tôi là thêm các phương thức vào lớp cho các đối tượng của tôi trả về giờ và phút. Tôi có thể nhận được số giờ bằng cách chia timedelta.seconds cho 3600 và làm tròn số đó. Tôi gặp rắc rối với việc lấy các giây còn lại và chuyển đổi nó thành phút.

Nhân tiện, tôi đang sử dụng Google AppEngine với Mẫu Django để trình bày.


44
Sẽ rất tuyệt nếu timedelta có tương đương với phương thức strftime ().
JS.

@JS. Vâng, bạn phần nào có thể nếu bạn sử dụng datetime.utcfromtimestamp(). Xem câu trả lời của tôi dưới đây.
sjngm

@JS. - 100% đồng ý. Sau đó, __str__các timedeltakhá đàng hoàng, như trái ngược với __repr__(có nghĩa là - đối với con người). Ví dụ: datetime.timedelta(minutes=6, seconds=41) * 2618 / 48cho datetime.timedelta(seconds=21871, microseconds=208333), nhưng str(datetime.timedelta(minutes=6, seconds=41) * 2618 / 48)cho '6:04:31.208333'là khá ổn để đọc.
Tomasz Gandor

Câu trả lời:


213

Bạn chỉ có thể chuyển đổi timedelta thành một chuỗi với str (). Đây là một ví dụ:

import datetime
start = datetime.datetime(2009,2,10,14,00)
end   = datetime.datetime(2009,2,10,16,00)
delta = end-start
print(str(delta))
# prints 2:00:00

13
Giống như gọi phương thức str () với timedelta làm đối số của nó.
joeforker

12
Bạn không cần cuộc gọi str ở đó, nó sẽ được thực hiện tự động bằng cách in.
Zitrax

5
@Zitrax nhưng nó là cần thiết nếu bạn sẽ nối đồng bằng với một chuỗi khác. Chẳng hạnprint 'some thing ' + str(delta)
Plinio.Santos

12
Và cần thiết khi loại dữ liệu được xác định là 'datetime.timedelta' và bạn đang sử dụng nó như thế này ConvertDuration=datetime.timedelta(milliseconds=int(254459))thì bạn chỉ cần sử dụng split để có được micro giây khi chơi. Từ 0: 03: 43.765000 Tôi có thể nhận được 0:03:43 chỉ bằng cách chạyTotalDuration=str(ConvertDuration).split('.', 2)[0]
DarkXDroid

16
Điều này có thể in delta dưới dạng một chuỗi, nhưng nó không định dạng nó như OP yêu cầu.
Dannid

187

Như bạn biết, bạn có thể nhận được tổng số giây từ một đối tượng timedelta bằng cách truy cập .secondsthuộc tính.

Python cung cấp hàm dựng sẵn divmod()cho phép:

s = 13420
hours, remainder = divmod(s, 3600)
minutes, seconds = divmod(remainder, 60)
print '{:02}:{:02}:{:02}'.format(int(hours), int(minutes), int(seconds))
# result: 03:43:40

hoặc bạn có thể chuyển đổi thành giờ và phần còn lại bằng cách sử dụng kết hợp modulo và phép trừ:

# arbitrary number of seconds
s = 13420
# hours
hours = s // 3600 
# remaining seconds
s = s - (hours * 3600)
# minutes
minutes = s // 60
# remaining seconds
seconds = s - (minutes * 60)
# total time
print '{:02}:{:02}:{:02}'.format(int(hours), int(minutes), int(seconds))
# result: 03:43:40

5
Đối với timedeltas tiêu cực, bạn nên đánh giá các dấu hiệu đầu tiên và sau đó làm abs(s).
mbarkhau

27
Lưu ý rằng bạn thực sự có thể muốn sử dụng '%d:%02d:%02d'để có các số 0 đứng đầu trong chuỗi đầu ra.
ShinNoNoir

12
cho python 2.7 và sử dụng nhiều hơn phương thức .total_seconds ()
sk8asd123

27
Không sử dụng .secondsnếu chênh lệch có thể âm hoặc dài hơn 24 giờ ( .secondsbỏ qua thuộc tính .days). Sử dụng .total_seconds()hoặc tương tự của nó thay thế.
JFS

Đối với sự khác biệt tích cực, tôi thỉnh thoảng thực hiện lại điều này. Cảm ơn bạn chỉ cần tìm kiếm lần này :)
Wolf

59
>>> str(datetime.timedelta(hours=10.56))
10:33:36

>>> td = datetime.timedelta(hours=10.505) # any timedelta object
>>> ':'.join(str(td).split(':')[:2])
10:30

Truyền timedeltađối tượng cho str()hàm gọi cùng một mã định dạng được sử dụng nếu chúng ta chỉ cần gõ print td. Vì bạn không muốn có giây, chúng tôi có thể chia chuỗi bằng dấu hai chấm (3 phần) và đặt lại chuỗi chỉ với 2 phần đầu tiên.


Cảm ơn câu trả lời của bạn joeforker, nhưng tôi không chắc là tôi hiểu câu trả lời của bạn. Tôi nhận được một delta thời gian bằng cách datetime - datetime. Tôi không biết giờ. Thêm vào đó, có vẻ như ví dụ của bạn bao gồm vài giây, tôi sẽ xóa nó như thế nào?
mawcs

1
Không quan trọng bạn lấy đối tượng timedelta ở đâu, nó sẽ định dạng giống nhau.
joeforker

9
Nếu nó dài hơn một ngày, nó sẽ định dạng như "4 ngày, 8:00" sau khi xử lý tách / nối.
joeforker

4
str(my_timedelta)hoạt động kém hiệu quả đối với các số âm
Catskul

2
Cũng hiển thị các ngày khi> 24 giờ, ví dụ '4 ngày, 18: 48: 22.330000'. Nhiều phương pháp khuyên ở đây không.
Alexei Martianov

47
def td_format(td_object):
    seconds = int(td_object.total_seconds())
    periods = [
        ('year',        60*60*24*365),
        ('month',       60*60*24*30),
        ('day',         60*60*24),
        ('hour',        60*60),
        ('minute',      60),
        ('second',      1)
    ]

    strings=[]
    for period_name, period_seconds in periods:
        if seconds > period_seconds:
            period_value , seconds = divmod(seconds, period_seconds)
            has_s = 's' if period_value > 1 else ''
            strings.append("%s %s%s" % (period_value, period_name, has_s))

    return ", ".join(strings)

3
Thực sự tốt đẹp, tôi sẽ đề nghị thay đổi if seconds > period_seconds:để if seconds >= period_seconds:tuy nhiên.
CBenni

1
Điều này trả về các chuỗi trống cho timedeltas âm, không chắc chắn nếu điều này được dự định?
Dirk

31

Cá nhân tôi sử dụng humanizethư viện cho việc này:

>>> import datetime
>>> humanize.naturalday(datetime.datetime.now())
'today'
>>> humanize.naturalday(datetime.datetime.now() - datetime.timedelta(days=1))
'yesterday'
>>> humanize.naturalday(datetime.date(2007, 6, 5))
'Jun 05'
>>> humanize.naturaldate(datetime.date(2007, 6, 5))
'Jun 05 2007'
>>> humanize.naturaltime(datetime.datetime.now() - datetime.timedelta(seconds=1))
'a second ago'
>>> humanize.naturaltime(datetime.datetime.now() - datetime.timedelta(seconds=3600))
'an hour ago'

Tất nhiên, nó không cung cấp cho bạn chính xác câu trả lời mà bạn đang tìm kiếm (thực sự là vậy str(timeA - timeB), nhưng tôi đã thấy rằng một khi bạn vượt quá vài giờ, màn hình sẽ nhanh chóng không thể đọc được.humanize Có hỗ trợ cho các giá trị lớn hơn nhiều con người có thể đọc được, và cũng được bản địa hóa.

Nó được lấy cảm hứng từ contrib.humanizemô-đun của Django , vì vậy, vì bạn đang sử dụng Django, có lẽ bạn nên sử dụng nó.


2
Đẹp, + 1 Mặc dù: humanize.naturaldelta (pd.Timedelta ('- 10 giây')) -> '10 giây ': S ...
ntg

2
cũng một đồng bằng 10 giây . :) nó bạn muốn thời gian , naturaltimelà những gì bạn muốn sử dụng.
Anarcat

28

Anh ta đã có một đối tượng timedelta, vậy tại sao không sử dụng phương thức tích hợp Total_seconds () để chuyển đổi nó thành giây, sau đó sử dụng divmod () để lấy giờ và phút?

hours, remainder = divmod(myTimeDelta.total_seconds(), 3600)
minutes, seconds = divmod(remainder, 60)

# Formatted only for hours and minutes as requested
print '%s:%s' % (hours, minutes)

Điều này hoạt động bất kể nếu đồng bằng thời gian có thậm chí ngày hoặc năm.


23

Đây là một hàm mục đích chung để chuyển đổi một timedeltađối tượng hoặc một số thông thường (dưới dạng giây hoặc phút, v.v.) thành một chuỗi được định dạng độc đáo. Tôi đã lấy câu trả lời tuyệt vời của mpounsett cho một câu hỏi trùng lặp, làm cho nó linh hoạt hơn một chút, cải thiện khả năng đọc và thêm tài liệu.

Bạn sẽ thấy rằng đó là câu trả lời linh hoạt nhất ở đây cho đến nay vì nó cho phép bạn:

  1. Tùy chỉnh định dạng chuỗi một cách nhanh chóng thay vì nó được mã hóa cứng.
  2. Để lại các khoảng thời gian nhất định mà không có vấn đề (xem ví dụ dưới đây).

Chức năng:

from string import Formatter
from datetime import timedelta

def strfdelta(tdelta, fmt='{D:02}d {H:02}h {M:02}m {S:02}s', inputtype='timedelta'):
    """Convert a datetime.timedelta object or a regular number to a custom-
    formatted string, just like the stftime() method does for datetime.datetime
    objects.

    The fmt argument allows custom formatting to be specified.  Fields can 
    include seconds, minutes, hours, days, and weeks.  Each field is optional.

    Some examples:
        '{D:02}d {H:02}h {M:02}m {S:02}s' --> '05d 08h 04m 02s' (default)
        '{W}w {D}d {H}:{M:02}:{S:02}'     --> '4w 5d 8:04:02'
        '{D:2}d {H:2}:{M:02}:{S:02}'      --> ' 5d  8:04:02'
        '{H}h {S}s'                       --> '72h 800s'

    The inputtype argument allows tdelta to be a regular number instead of the  
    default, which is a datetime.timedelta object.  Valid inputtype strings: 
        's', 'seconds', 
        'm', 'minutes', 
        'h', 'hours', 
        'd', 'days', 
        'w', 'weeks'
    """

    # Convert tdelta to integer seconds.
    if inputtype == 'timedelta':
        remainder = int(tdelta.total_seconds())
    elif inputtype in ['s', 'seconds']:
        remainder = int(tdelta)
    elif inputtype in ['m', 'minutes']:
        remainder = int(tdelta)*60
    elif inputtype in ['h', 'hours']:
        remainder = int(tdelta)*3600
    elif inputtype in ['d', 'days']:
        remainder = int(tdelta)*86400
    elif inputtype in ['w', 'weeks']:
        remainder = int(tdelta)*604800

    f = Formatter()
    desired_fields = [field_tuple[1] for field_tuple in f.parse(fmt)]
    possible_fields = ('W', 'D', 'H', 'M', 'S')
    constants = {'W': 604800, 'D': 86400, 'H': 3600, 'M': 60, 'S': 1}
    values = {}
    for field in possible_fields:
        if field in desired_fields and field in constants:
            values[field], remainder = divmod(remainder, constants[field])
    return f.format(fmt, **values)

Bản giới thiệu:

>>> td = timedelta(days=2, hours=3, minutes=5, seconds=8, microseconds=340)

>>> print strfdelta(td)
02d 03h 05m 08s

>>> print strfdelta(td, '{D}d {H}:{M:02}:{S:02}')
2d 3:05:08

>>> print strfdelta(td, '{D:2}d {H:2}:{M:02}:{S:02}')
 2d  3:05:08

>>> print strfdelta(td, '{H}h {S}s')
51h 308s

>>> print strfdelta(12304, inputtype='s')
00d 03h 25m 04s

>>> print strfdelta(620, '{H}:{M:02}', 'm')
10:20

>>> print strfdelta(49, '{D}d {H}h', 'h')
2d 1h

Rất đẹp, sạch mã! Tôi tự hỏi làm thế nào mã này có thể được mở rộng để xử lý các giây còn lại cuối cùng trong bộ định dạng ...
kfmfe04

17

Tôi biết rằng đây là một câu hỏi đã trả lời cũ, nhưng tôi sử dụng datetime.utcfromtimestamp()cho câu hỏi này. Phải mất số giây và trả về một datetimecó thể được định dạng như bất kỳ khác datetime.

duration = datetime.utcfromtimestamp(end - begin)
print duration.strftime('%H:%M')

Miễn là bạn ở trong phạm vi pháp lý cho các phần thời gian thì điều này sẽ hoạt động, tức là nó không trả về 1234: 35 vì số giờ là <= 23.


2
bạn nên sử dụng print timedelta(seconds=end - begin)thay thế.
JFS

@JFSebastian Sau đó, bạn phải đệm giờ theo cách thủ công với các số 0 hàng đầu.
sjngm

Tôi không thấy gì về phần đệm trong câu hỏi. Sử dụng .zfill(8)nếu bạn cần nó.
jfs

1
Cần một cuộc gọi .total_seconds (): >>> datetime.utcfromtimestamp ((t2-t1) .total_seconds ()). Strftime ("% H:% M:% S") <<< >>> '00: 00: 05 '
cagney

2
Tôi rất thích giải pháp này, nó cho phép bạn kiểm soát định dạng. Lưu ý rằng bạn cũng có thể sử dụng trình định dạng str trực tiếp như thế này: "{0:% H}: {0:% M}". Định dạng (thời lượng)
ngón chân

15

Người hỏi muốn một định dạng đẹp hơn so với điển hình:

  >>> import datetime
  >>> datetime.timedelta(seconds=41000)
  datetime.timedelta(0, 41000)
  >>> str(datetime.timedelta(seconds=41000))
  '11:23:20'
  >>> str(datetime.timedelta(seconds=4102.33))
  '1:08:22.330000'
  >>> str(datetime.timedelta(seconds=413302.33))
  '4 days, 18:48:22.330000'

Vì vậy, thực sự có hai định dạng, một trong đó ngày là 0 và nó bị bỏ qua và một định dạng khác có văn bản "n ngày, h: m: s". Nhưng, giây có thể có phân số và không có số 0 đứng đầu trong bản in, vì vậy các cột rất lộn xộn.

Đây là thói quen của tôi, nếu bạn thích nó:

def printNiceTimeDelta(stime, etime):
    delay = datetime.timedelta(seconds=(etime - stime))
    if (delay.days > 0):
        out = str(delay).replace(" days, ", ":")
    else:
        out = "0:" + str(delay)
    outAr = out.split(':')
    outAr = ["%02d" % (int(float(x))) for x in outAr]
    out   = ":".join(outAr)
    return out

cái này trả về đầu ra dưới dạng dd: hh: mm: ss:

00:00:00:15
00:00:00:19
02:01:31:40
02:01:32:22

Tôi đã nghĩ về việc thêm nhiều năm cho việc này, nhưng điều này chỉ là một bài tập cho người đọc, vì đầu ra an toàn ở mức hơn 1 năm:

>>> str(datetime.timedelta(seconds=99999999))
'1157 days, 9:46:39'

15

Tôi sẽ nghiêm túc xem xét phương pháp Occam's Razor ở đây:

td = str(timedelta).split('.')[0]

Điều này trả về một chuỗi không có micro giây

Nếu bạn muốn tạo lại đối tượng datetime.timedelta, chỉ cần làm điều này:

h,m,s = re.split(':', td)
new_delta = datetime.timedelta(hours=int(h),minutes=int(m),seconds=int(s))

2 năm sau, tôi yêu ngôn ngữ này!


5
Điều này không bao gồm ngày
Waschbaer

13

datetime.timedeltaĐối tượng của tôi đã đi hơn một ngày. Vì vậy, đây là một vấn đề xa hơn. Tất cả các cuộc thảo luận ở trên giả định ít hơn một ngày. A timedeltathực sự là một tuple của ngày, giây và micro giây. Các cuộc thảo luận ở trên nên sử dụngtd.seconds như joe đã làm, nhưng nếu bạn có ngày thì KHÔNG được tính vào giá trị giây.

Tôi nhận được một khoảng thời gian giữa 2 datetimes và ngày và giờ in.

span = currentdt - previousdt
print '%d,%d\n' % (span.days,span.seconds/3600)

Đây là giải pháp bằng chứng trong tương lai.
Jibin

11

Tôi đã sử dụng humanfriendlythư viện python để làm điều này, nó hoạt động rất tốt.

import humanfriendly
from datetime import timedelta
delta = timedelta(seconds = 321)
humanfriendly.format_timespan(delta)

'5 minutes and 21 seconds'

Có sẵn tại https://pypi.org/project/humanfriendly/


7

Theo giá trị mẫu của Joe ở trên, tôi sẽ sử dụng toán tử số học mô đun, do đó:

td = datetime.timedelta(hours=10.56)
td_str = "%d:%d" % (td.seconds/3600, td.seconds%3600/60)

Lưu ý rằng phân chia số nguyên trong Python làm tròn xuống theo mặc định; nếu bạn muốn rõ ràng hơn, hãy sử dụng math.floor () hoặc math.ceil () nếu thích hợp.


timedelta đã biết cách định dạng chính nó, như trong 'in some_timedelta'.
joeforker

Vâng, nhưng nó không thể chấp nhận một chuỗi định dạng tùy ý, đó là những gì Michael đã yêu cầu. Mặc dù bây giờ tôi nghĩ về nó, mod chia 3600 tạo ra giả định giờ-giây gây ra vấn đề ở giây nhuận.
UltraNurd

Vâng, nhưng anh ta không muốn một chuỗi định dạng tùy ý, anh ta muốn gần như chính xác hành vi mặc định.
joeforker

2
Đừng quên // để cắt bớt phân chia trong Python 3000
joeforker

3
+1, nhưng tại sao bạn không chỉnh sửa câu trả lời để sử dụng //? Tôi cũng đề nghị sử dụng td.total_seconds()thay vì .secondsđể nó hoạt động trong khoảng thời gian> 1 ngày.
Antony Hatchkins

4
def seconds_to_time_left_string(total_seconds):
    s = int(total_seconds)
    years = s // 31104000
    if years > 1:
        return '%d years' % years
    s = s - (years * 31104000)
    months = s // 2592000
    if years == 1:
        r = 'one year'
        if months > 0:
            r += ' and %d months' % months
        return r
    if months > 1:
        return '%d months' % months
    s = s - (months * 2592000)
    days = s // 86400
    if months == 1:
        r = 'one month'
        if days > 0:
            r += ' and %d days' % days
        return r
    if days > 1:
        return '%d days' % days
    s = s - (days * 86400)
    hours = s // 3600
    if days == 1:
        r = 'one day'
        if hours > 0:
            r += ' and %d hours' % hours
        return r 
    s = s - (hours * 3600)
    minutes = s // 60
    seconds = s - (minutes * 60)
    if hours >= 6:
        return '%d hours' % hours
    if hours >= 1:
        r = '%d hours' % hours
        if hours == 1:
            r = 'one hour'
        if minutes > 0:
            r += ' and %d minutes' % minutes
        return r
    if minutes == 1:
        r = 'one minute'
        if seconds > 0:
            r += ' and %d seconds' % seconds
        return r
    if minutes == 0:
        return '%d seconds' % seconds
    if seconds == 0:
        return '%d minutes' % minutes
    return '%d minutes and %d seconds' % (minutes, seconds)

for i in range(10):
    print pow(8, i), seconds_to_time_left_string(pow(8, i))


Output:
1 1 seconds
8 8 seconds
64 one minute and 4 seconds
512 8 minutes and 32 seconds
4096 one hour and 8 minutes
32768 9 hours
262144 3 days
2097152 24 days
16777216 6 months
134217728 4 years

Bạn đã viết cái này? Bạn đã kiểm tra nó bao nhiêu?
Thomas Ahle

Tôi đang sử dụng mã này trong dự án của tôi được gọi là datahaven.net . Nó hoạt động khá tốt. Bạn có thấy lỗi nào không?
Veselin Penev

Thật tuyệt nếu bạn có thể cung cấp một chút thông tin với câu trả lời nặng về mã như vậy :) Giống như một ví dụ về cách thức hoạt động, các điểm mạnh và điểm yếu có thể có.
Thomas Ahle

1
Oh. Chắc chắn rồi!. Đã thêm một ví dụ cho bạn. :-)
Veselin Penev

Siêu :) Cũng thông báo rằng timedeltađối tượng có các lĩnh vực days, secondsmicrosecondsbằng tài liệu.
Thomas Ahle

4

Tôi đã có một vấn đề tương tự với đầu ra của tính toán ngoài giờ tại nơi làm việc. Giá trị phải luôn hiển thị trong HH: MM, ngay cả khi nó lớn hơn một ngày và giá trị có thể bị âm. Tôi đã kết hợp một số giải pháp được hiển thị và có thể người khác thấy giải pháp này hữu ích. Tôi nhận ra rằng nếu giá trị timedelta là âm hầu hết các giải pháp được hiển thị với phương thức divmod sẽ không hoạt động:

def td2HHMMstr(td):
  '''Convert timedelta objects to a HH:MM string with (+/-) sign'''
  if td < datetime.timedelta(seconds=0):
    sign='-'
    td = -td
  else:
    sign = ''
  tdhours, rem = divmod(td.total_seconds(), 3600)
  tdminutes, rem = divmod(rem, 60)
  tdstr = '{}{:}:{:02d}'.format(sign, int(tdhours), int(tdminutes))
  return tdstr

timedelta đến chuỗi HH: MM:

td2HHMMstr(datetime.timedelta(hours=1, minutes=45))
'1:54'

td2HHMMstr(datetime.timedelta(days=2, hours=3, minutes=2))
'51:02'

td2HHMMstr(datetime.timedelta(hours=-3, minutes=-2))
'-3:02'

td2HHMMstr(datetime.timedelta(days=-35, hours=-3, minutes=-2))
'-843:02'

4
import datetime
hours = datetime.timedelta(hours=16, minutes=30)
print((datetime.datetime(1,1,1) + hours).strftime('%H:%M'))

2
trong 3.7 Tôi nhận được AttributionError: đối tượng 'datetime.timedelta' không có thuộc tính 'strftime'
qubodup

4

Một bộ lọc mẫu thẳng về phía trước cho vấn đề này. Hàm int () tích hợp không bao giờ làm tròn. Chuỗi F (tức là f '') yêu cầu python 3.6.

@app_template_filter()
def diffTime(end, start):
    diff = (end - start).total_seconds()
    d = int(diff / 86400)
    h = int((diff - (d * 86400)) / 3600)
    m = int((diff - (d * 86400 + h * 3600)) / 60)
    s = int((diff - (d * 86400 + h * 3600 + m *60)))
    if d > 0:
        fdiff = f'{d}d {h}h {m}m {s}s'
    elif h > 0:
        fdiff = f'{h}h {m}m {s}s'
    elif m > 0:
        fdiff = f'{m}m {s}s'
    else:
        fdiff = f'{s}s'
    return fdiff

3
from django.utils.translation import ngettext

def localize_timedelta(delta):
    ret = []
    num_years = int(delta.days / 365)
    if num_years > 0:
        delta -= timedelta(days=num_years * 365)
        ret.append(ngettext('%d year', '%d years', num_years) % num_years)

    if delta.days > 0:
        ret.append(ngettext('%d day', '%d days', delta.days) % delta.days)

    num_hours = int(delta.seconds / 3600)
    if num_hours > 0:
        delta -= timedelta(hours=num_hours)
        ret.append(ngettext('%d hour', '%d hours', num_hours) % num_hours)

    num_minutes = int(delta.seconds / 60)
    if num_minutes > 0:
        ret.append(ngettext('%d minute', '%d minutes', num_minutes) % num_minutes)

    return ' '.join(ret)

Điều này sẽ tạo ra:

>>> from datetime import timedelta
>>> localize_timedelta(timedelta(days=3660, minutes=500))
'10 years 10 days 8 hours 20 minutes'

Theo ý kiến ​​của tôi, gọn gàng nhất về chiều dài và những gì nó bao gồm
Dici

1

Vui lòng kiểm tra chức năng này - nó chuyển đổi đối tượng timedelta thành chuỗi '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)

1

Lót. Vì timedeltas không cung cấp strftime's datetime, hãy đưa timedelta trở lại datetime và sử dụng stftime.

Điều này không chỉ có thể đạt được định dạng được yêu cầu của OP Giờ: Phút, giờ đây bạn có thể tận dụng toàn bộ sức mạnh định dạng của các chuỗi thời gian của datetime, nếu các yêu cầu của bạn thay đổi thành biểu diễn khác.

import datetime
td = datetime.timedelta(hours=2, minutes=10, seconds=5)
print(td)
print(datetime.datetime.strftime(datetime.datetime.strptime(str(td), "%H:%M:%S"), "%H:%M"))

Output:
2:10:05
02:10

Điều này cũng giải quyết được sự khó chịu khi các khung thời gian được định dạng thành các chuỗi là H: MM: SS chứ không phải HH: MM: SS, dẫn tôi đến vấn đề này và giải pháp tôi đã chia sẻ.


0

Nếu bạn đã có obj timedelta thì chỉ cần chuyển obj đó thành chuỗi. Xóa 3 ký tự cuối cùng của chuỗi và in. Điều này sẽ cắt bớt phần giây và in phần còn lại của nó ở định dạng Giờ: Phút.

t = str(timedeltaobj) 

print t[:-3]

-3 không hoạt động, sử dụng tốt hơnprint t.split('.')[0]
EvgenyKolyakov

0

Nếu bạn tình cờ có IPythontrong các gói của mình (bạn nên), thì nó có (cho đến nay, dù sao đi nữa) một định dạng rất đẹp cho thời lượng (tính bằng giây trôi nổi). Điều đó được sử dụng ở nhiều nơi, ví dụ như %%timema thuật tế bào. Tôi thích định dạng mà nó tạo ra cho thời lượng ngắn:

>>> from IPython.core.magics.execution import _format_time
>>> 
>>> for v in range(-9, 10, 2):
...     dt = 1.25 * 10**v
...     print(_format_time(dt))

1.25 ns
125 ns
12.5 µs
1.25 ms
125 ms
12.5 s
20min 50s
1d 10h 43min 20s
144d 16h 13min 20s
14467d 14h 13min 20s

-3
t1 = datetime.datetime.strptime(StartTime, "%H:%M:%S %d-%m-%y")

t2 = datetime.datetime.strptime(EndTime, "%H:%M:%S %d-%m-%y")

return str(t2-t1)

Vì vậy đối với:

StartTime = '15:28:53 21-07-13'
EndTime = '15:32:40 21-07-13'

trả về:

'0:03:47'

-10

Cảm ơn mọi người đã giúp đỡ. Tôi lấy nhiều ý tưởng của bạn và đặt chúng lại với nhau, cho tôi biết bạn nghĩ gì.

Tôi đã thêm hai phương thức vào lớp như thế này:

def hours(self):
    retval = ""
    if self.totalTime:
        hoursfloat = self.totalTime.seconds / 3600
        retval = round(hoursfloat)
    return retval

def minutes(self):
    retval = ""
    if self.totalTime:
        minutesfloat = self.totalTime.seconds / 60
        hoursAsMinutes = self.hours() * 60
        retval = round(minutesfloat - hoursAsMinutes)
    return retval

Trong django của tôi, tôi đã sử dụng cái này (sum là đối tượng và nó nằm trong từ điển):

<td>{{ sum.0 }}</td>    
<td>{{ sum.1.hours|stringformat:"d" }}:{{ sum.1.minutes|stringformat:"#02.0d" }}</td>

Nó hơi dài. Tôi muốn đề xuất: def hhmm (self): return ':'. Tham gia (str (td) .split (':') [: 2]) <td> {{sum.1.hhmm}} </ td>
joeforker

1
Chỉ cần sử dụng divmod () như thể hiện trong ví dụ "Sự khác biệt của hai ngày" tại docs.python.org/release/2.5.2/lib/datetime-timedelta.html
Tom
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.