Format timedelta ke string

275

Saya mengalami kesulitan memformat datetime.timedeltaobjek.

Inilah yang saya coba lakukan: Saya memiliki daftar objek dan salah satu anggota kelas objek adalah objek timedelta yang menunjukkan durasi suatu peristiwa. Saya ingin menampilkan durasi itu dalam format jam: menit.

Saya telah mencoba berbagai metode untuk melakukan ini dan saya mengalami kesulitan. Pendekatan saya saat ini adalah menambahkan metode ke kelas untuk objek saya yang menghasilkan jam dan menit. Saya bisa mendapatkan jam dengan membagi timedelta.seconds dengan 3600 dan membulatkannya. Saya mengalami masalah dengan mendapatkan sisa detik dan mengubahnya menjadi menit.

Omong-omong, saya menggunakan Google AppEngine dengan Django Templates untuk presentasi.

mawc
sumber
44
Akan lebih baik jika timedelta memiliki yang setara dengan metode strftime ().
JS.
@ JS. Yah, Anda agak bisa jika Anda gunakan datetime.utcfromtimestamp(). Lihat jawaban saya di bawah ini.
sjngm
@ JS. - 100% setuju. Maka, __str__dari timedeltacukup layak, sebagai lawan __repr__(yaitu - untuk manusia!). Misalnya: datetime.timedelta(minutes=6, seconds=41) * 2618 / 48memberi datetime.timedelta(seconds=21871, microseconds=208333), tetapi str(datetime.timedelta(minutes=6, seconds=41) * 2618 / 48)memberi '6:04:31.208333'yang cukup OK untuk dibaca.
Tomasz Gandor

Jawaban:

213

Anda bisa mengonversi timedelta menjadi string dengan str (). Ini sebuah contoh:

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
Parand
sumber
13
Lebih mirip memanggil metode str () dengan timedelta sebagai argumennya.
joeforker
12
Anda tidak perlu panggilan ke sana, itu akan dilakukan secara otomatis dengan mencetak.
Zitrax
5
@Zitrax tetapi perlu jika Anda akan menggabungkan delta dengan string lain. Misalnyaprint 'some thing ' + str(delta)
Plinio.Santos
13
Dan diperlukan ketika tipe data didefinisikan sebagai 'datetime.timedelta' dan Anda menggunakannya seperti ini ConvertDuration=datetime.timedelta(milliseconds=int(254459))maka Anda hanya menggunakan split untuk mengeluarkan mikrodetik dari permainan. Dari 0: 03: 43.765000 saya bisa mendapatkan 0:03:43 hanya dengan menjalankanTotalDuration=str(ConvertDuration).split('.', 2)[0]
DarkXDroid
16
Ini mungkin mencetak delta sebagai string, tetapi tidak memformatnya seperti yang diminta OP.
Dannid
187

Seperti yang Anda ketahui, Anda bisa mendapatkan total_seconds dari objek timedelta dengan mengakses .secondsatribut.

Python menyediakan fungsi bawaan divmod()yang memungkinkan untuk:

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

atau Anda dapat mengonversi menjadi berjam-jam dan sisanya dengan menggunakan kombinasi modulo dan pengurangan:

# 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
John Fouhy
sumber
5
Untuk timedeltas negatif Anda harus mengevaluasi tanda terlebih dahulu dan kemudian lakukan abs(s).
mbarkhau
27
Perhatikan bahwa Anda mungkin benar-benar ingin menggunakan '%d:%02d:%02d'untuk memiliki nol di dalam string keluaran.
ShinNoNoir
12
untuk python 2.7 dan penggunaan yang lebih besar .total_seconds () method
sk8asd123
27
Jangan gunakan .secondsjika perbedaannya bisa negatif atau lebih dari 24 jam ( .secondsatribut diabaikan .days). Gunakan .total_seconds()atau analognya saja.
jfs
Untuk perbedaan positif, saya menerapkan kembali ini dari waktu ke waktu. Terima kasih untuk hanya mencari kali ini :)
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

Melewati timedeltaobjek ke str()fungsi memanggil kode pemformatan yang sama yang digunakan jika kita cukup mengetik print td. Karena Anda tidak menginginkan detik, kami dapat memisahkan string dengan titik dua (3 bagian) dan memasangnya kembali hanya dengan 2 bagian pertama.

joeforker
sumber
Terima kasih atas jawaban Anda, Joeforker, tetapi saya tidak yakin saya mengerti respons Anda. Saya mendapatkan delta waktu melalui datetime - datetime. Saya tidak tahu jam berapa. Plus, sepertinya contoh Anda termasuk detik, bagaimana saya menghapus itu?
mawcs
1
Tidak masalah dari mana Anda mendapatkan objek timedelta, itu akan memformat yang sama.
joeforker
9
Jika lebih dari satu hari, itu akan memformat seperti misalnya "4 hari, 8:00" setelah pemrosesan split / join.
joeforker
4
str(my_timedelta)bekerja buruk untuk angka negatif
Catskul
2
Juga menunjukkan hari ketika> 24 jam, misalnya '4 hari, 18: 48: 22.330000'. Banyak metode yang disarankan di sini tidak.
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)
Adam Jacob Muller
sumber
3
Sangat bagus, saya akan menyarankan if seconds > period_seconds:untuk berubah if seconds >= period_seconds:.
CBenni
1
Ini mengembalikan string kosong untuk timedeltas negatif, tidak yakin apakah ini dimaksudkan?
Dirk
31

Saya pribadi menggunakan humanizeperpustakaan untuk ini:

>>> 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'

Tentu saja, itu tidak memberi Anda jawaban tepat yang Anda cari (yang memang str(timeA - timeB), tapi saya telah menemukan bahwa setelah Anda melampaui beberapa jam, tampilan menjadi cepat tidak dapat dibaca.humanize Memiliki dukungan untuk nilai yang jauh lebih besar yang dapat dibaca oleh manusia, dan juga terlokalisasi dengan baik.

Ini terinspirasi oleh contrib.humanizemodul Django , rupanya, jadi karena Anda menggunakan Django, Anda mungkin harus menggunakannya.

anarcat
sumber
2
Nice, +1 Meskipun: memanusiakan.naturaldelta (pd.Timedelta ('- 10sec')) -> '10 detik ': S ...
ntg
2
baik itu adalah delta 10 detik . :) itu Anda ingin waktu , naturaltimeadalah apa yang ingin Anda gunakan.
anarcat
28

Dia sudah memiliki objek timedelta jadi mengapa tidak menggunakan metode built-in total_seconds () untuk mengubahnya menjadi detik, lalu gunakan divmod () untuk mendapatkan jam dan menit?

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)

Ini berfungsi terlepas dari apakah waktu delta bahkan berhari-hari atau bertahun-tahun.

Bill Kidd
sumber
23

Berikut adalah fungsi tujuan umum untuk mengonversi timedeltaobjek atau angka biasa (dalam bentuk detik atau menit, dll.) Ke string yang diformat dengan baik. Saya mengambil jawaban mpounsett yang luar biasa pada pertanyaan duplikat, membuatnya sedikit lebih fleksibel, meningkatkan daya tampung, dan menambahkan dokumentasi.

Anda akan menemukan bahwa itu adalah jawaban yang paling fleksibel di sini sejauh ini karena memungkinkan Anda untuk:

  1. Kustomisasi format string dengan cepat alih-alih menjadi hard-coded.
  2. Biarkan interval waktu tertentu tanpa masalah (lihat contoh di bawah).

Fungsi:

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)

Demo:

>>> 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
MarredCheese
sumber
Sangat bagus, kode bersih! Saya bertanya-tanya bagaimana kode ini dapat diperluas untuk menangani detik sisa fraksional terakhir di formatter ...
kfmfe04
17

Saya tahu ini adalah pertanyaan lama, tapi saya gunakan datetime.utcfromtimestamp()untuk ini. Dibutuhkan jumlah detik dan mengembalikan datetimeyang dapat diformat seperti yang lain datetime.

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

Selama Anda tetap berada dalam rentang hukum untuk bagian waktu ini akan berfungsi, yaitu tidak mengembalikan 1234: 35 karena jam adalah <= 23.

sjngm
sumber
2
Anda harus menggunakannya print timedelta(seconds=end - begin).
jfs
@ JFSebastian Maka Anda harus mengisi jam secara manual dengan nol terkemuka.
sjngm
Saya tidak melihat apa pun tentang pengisi dalam pertanyaan. Gunakan .zfill(8)jika Anda membutuhkannya.
jfs
1
Memerlukan .total_seconds () panggilan: >>> datetime.utcfromtimestamp ((t2-t1) .total_seconds ()). Strftime ("% H:% M:% S") <<< >>> '00: 00: 05 '
cagney
2
Saya lebih suka solusi ini, memungkinkan Anda untuk mengontrol pemformatan. Catatan Anda juga dapat menggunakan str formatter secara langsung seperti ini: "{0:% H}: {0:% M}" .format (durasi)
jari kaki
15

Penanya menginginkan format yang lebih bagus daripada biasanya:

  >>> 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'

Jadi, sungguh ada dua format, satu di mana hari adalah 0 dan itu ditinggalkan, dan yang lain di mana ada teks "n hari, h: m: s". Tetapi, detik-detik mungkin memiliki pecahan, dan tidak ada angka nol di depan dalam cetakan, sehingga kolom menjadi berantakan.

Inilah rutinitas saya, jika Anda suka:

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

ini mengembalikan output sebagai format dd: hh: mm: ss:

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

Saya memang berpikir untuk menambahkan tahun ke ini, tetapi ini dibiarkan sebagai latihan untuk pembaca, karena hasilnya aman di lebih dari 1 tahun:

>>> str(datetime.timedelta(seconds=99999999))
'1157 days, 9:46:39'
Kevin J. Rice
sumber
15

Saya serius mempertimbangkan pendekatan Occam's Razor di sini:

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

Ini mengembalikan string tanpa mikrodetik

Jika Anda ingin membuat ulang objek datetime.timedelta, lakukan ini:

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

2 tahun, saya suka bahasa ini!

Pyrotherm
sumber
5
Ini tidak mencakup hari
Waschbaer
13

datetime.timedeltaBenda-benda saya menjadi lebih besar dari satu hari. Jadi inilah masalah selanjutnya. Semua diskusi di atas mengasumsikan kurang dari sehari. A timedeltasebenarnya adalah tuple hari, detik dan mikrodetik. Diskusi di atas harus digunakantd.seconds seperti yang dilakukan joe, tetapi jika Anda punya hari, itu TIDAK termasuk dalam nilai detik.

Saya mendapatkan rentang waktu antara 2 datetimes dan mencetak hari dan jam.

span = currentdt - previousdt
print '%d,%d\n' % (span.days,span.seconds/3600)
Alex L
sumber
Ini adalah solusi bukti masa depan.
Jibin
11

Saya menggunakan humanfriendlypustaka python untuk melakukan ini, ia bekerja dengan sangat baik.

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

'5 minutes and 21 seconds'

Tersedia di https://pypi.org/project/humanfriendly/

Dhiraj Gupta
sumber
7

Mengikuti nilai contoh Joe di atas, saya akan menggunakan operator modulus aritmatika, dengan demikian:

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

Perhatikan bahwa pembagian integer dalam Python dibulatkan secara default; jika Anda ingin lebih eksplisit, gunakan math.floor () atau math.ceil () yang sesuai.

UltraNurd
sumber
timedelta sudah tahu cara memformat dirinya sendiri, seperti pada 'print some_timedelta'.
joeforker
Ya, tapi itu tidak bisa menerima string format sewenang-wenang, itulah yang diminta Michael. Meskipun sekarang saya memikirkannya 3600 mod divisi membuat asumsi jam-detik yang menyebabkan masalah pada detik kabisat.
UltraNurd
Ya, tapi dia tidak ingin format string yang sewenang-wenang, dia ingin hampir persis perilaku default.
joeforker
2
Jangan lupa // untuk memotong divisi di Python 3000
joeforker
3
+1, tetapi mengapa Anda tidak mengedit jawaban untuk menggunakan //? Saya juga menyarankan menggunakan td.total_seconds()daripada .secondsmembuatnya bekerja untuk interval> 1 hari.
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
Veselin Penev
sumber
Apakah Anda menulis ini? Seberapa banyak Anda mengujinya?
Thomas Ahle
Saya menggunakan kode ini dalam proyek saya yang disebut datahaven.net . Ini bekerja dengan sangat baik. Apakah Anda melihat kesalahan?
Veselin Penev
Itu selalu baik jika Anda dapat memberikan sedikit informasi dengan kode seperti itu jawaban yang berat :) Seperti contoh cara kerjanya, kemungkinan kekuatan dan kelemahan.
Thomas Ahle
1
Oh Tentu!. Menambahkan contoh untuk Anda. :-)
Veselin Penev
Super :) Juga perhatikan bahwa timedelta objek memiliki bidang days, secondsdan microsecondsoleh dokumentasi.
Thomas Ahle
4

Saya memiliki masalah yang sama dengan hasil perhitungan lembur di tempat kerja. Nilai harus selalu muncul di HH: MM, bahkan ketika itu lebih besar dari satu hari dan nilainya bisa menjadi negatif. Saya menggabungkan beberapa solusi yang ditunjukkan dan mungkin orang lain menganggap solusi ini bermanfaat. Saya menyadari bahwa jika nilai timedelta negatif, sebagian besar solusi yang ditunjukkan dengan metode divmod tidak bekerja di luar kotak:

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 ke HH: MM string:

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'
nealtz
sumber
4
import datetime
hours = datetime.timedelta(hours=16, minutes=30)
print((datetime.datetime(1,1,1) + hours).strftime('%H:%M'))
SleX
sumber
2
di 3,7 saya mendapatkan AttributeError: objek 'datetime.timedelta' tidak memiliki atribut 'strftime'
qubodup
4

Filter template lurus ke depan untuk masalah ini. Fungsi built-in int () tidak pernah ditangkap. F-Strings (yaitu f '') membutuhkan 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
Patrick
sumber
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)

Ini akan menghasilkan:

>>> from datetime import timedelta
>>> localize_timedelta(timedelta(days=3660, minutes=500))
'10 years 10 days 8 hours 20 minutes'
Artem Vasilev
sumber
Yang paling rapi menurut saya, dalam hal panjang dan apa yang dicakupnya
Dici
1

Silakan periksa fungsi ini - ia mengubah objek timedelta menjadi string '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)
MobilePro.pl
sumber
1

Satu liner Karena timedeltas tidak menawarkan strimeime datetime, bawa timedelta kembali ke datetime, dan gunakan stftime.

Ini tidak hanya dapat mencapai format OP yang diminta Jam: Menit, sekarang Anda dapat memanfaatkan kekuatan format penuh dari waktu kerja datetime, jika persyaratan Anda berubah ke representasi lain.

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

Ini juga memecahkan gangguan yang timedeltas diformat menjadi string sebagai H: MM: SS daripada HH: MM: SS, yang membawa saya ke masalah ini, dan solusi yang saya bagikan.

Bill Gale
sumber
0

Jika Anda sudah memiliki obj timedelta maka cukup konversikan obj tersebut menjadi string. Hapus 3 karakter terakhir dari string dan cetak. Ini akan memotong bagian detik dan mencetak sisanya dalam format Jam: Menit.

t = str(timedeltaobj) 

print t[:-3]
Sima
sumber
-3 tidak bekerja, lebih baik digunakanprint t.split('.')[0]
EvgenyKolyakov
0

Jika Anda kebetulan ada IPythondalam paket Anda (Anda harus), itu memiliki (hingga sekarang, bagaimanapun) formatter yang sangat bagus untuk durasi (dalam float detik). Itu digunakan di berbagai tempat, misalnya dengan %%timesihir sel. Saya suka format yang dihasilkan untuk durasi pendek:

>>> 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
Pierre D
sumber
-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)

Sehingga untuk:

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

pengembalian:

'0:03:47'
Aviad
sumber
-10

Terima kasih semuanya atas bantuan Anda. Saya mengambil banyak ide Anda dan menggabungkannya, biarkan saya tahu apa yang Anda pikirkan.

Saya menambahkan dua metode ke kelas seperti ini:

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

Dalam Django saya, saya menggunakan ini (jumlah adalah objek dan itu dalam kamus):

<td>{{ sum.0 }}</td>    
<td>{{ sum.1.hours|stringformat:"d" }}:{{ sum.1.minutes|stringformat:"#02.0d" }}</td>
mawc
sumber
Agak panjang. Saya menyarankan: def hhmm (self): return ':'. Join (str (td) .split (':') [: 2]) <td> {{sum.1.hhmm}} </td>
joeforker
1
Cukup gunakan divmod () seperti yang ditunjukkan dalam contoh "Perbedaan Dua Tanggal" di docs.python.org/release/2.5.2/lib/datetime-timedelta.html
Tom