380

オブジェクトのフォーマットに問題がありdatetime.timedeltaます。

私がやろうとしているのは次のとおりです。オブジェクトのリストがあり、オブジェクトのクラスのメンバーの 1 つは、イベントの期間を示す timedelta オブジェクトです。その期間を時間:分の形式で表示したいと思います。

これを行うためにさまざまな方法を試しましたが、苦労しています。私の現在のアプローチは、時間と分を返すオブジェクトのクラスにメソッドを追加することです。timedelta.seconds を 3600 で割って四捨五入することで時間を取得できます。残りの秒数を取得して分に変換するのに問題があります。

ところで、プレゼンテーションには Google AppEngine と Django Templates を使用しています。

4

32 に答える 32

269

str() を使用して、timedelta を文字列に変換するだけです。次に例を示します。

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
于 2009-02-11T20:52:24.577 に答える
231

ご存知のように、.seconds属性にアクセスすることで、timedelta オブジェクトから total_seconds を取得できます。

Python は、以下を可能にする組み込み関数divmod()を提供します。

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

または、モジュロと減算の組み合わせを使用して、時間と剰余に変換できます。

# 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
于 2009-02-11T23:34:33.550 に答える
50

私は個人的にこれのためにhumanizeライブラリを使用します:

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

もちろん、それはあなたが探していた正確str(timeA - timeB)な答えを与えるわけではありません (実際には、ですが、数時間を超えると、ディスプレイがすぐに読めなくなることがわかりました.humanizeは、より大きな値をサポートしています。人間が読める形式であり、適切にローカライズされています。

どうやらDjangoのcontrib.humanizeモジュールに触発されているようで、Djangoを使用しているので、おそらくそれを使用する必要があります。

于 2016-11-17T16:30:26.513 に答える
31

彼はすでに timedelta オブジェクトを持っているので、組み込みメソッドの total_seconds() を使用して秒に変換してから、divmod() を使用して時間と分を取得してみませんか?

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)

これは、タイム デルタが偶数日であるか年であるかに関係なく機能します。

于 2013-06-19T15:41:24.767 に答える
16

ここで、オッカムのカミソリのアプローチを真剣に検討します。

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

これは、マイクロ秒なしの文字列を返します

datetime.timedelta オブジェクトを再生成する場合は、次のようにします。

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

2年で、私はこの言語が大好きです!

于 2015-02-25T22:53:28.840 に答える
15

質問者は、通常よりも優れた形式を望んでいます。

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

したがって、実際には 2 つの形式があります。1 つは日が 0 で省略されているもので、もう 1 つは "n days, h:m:s" というテキストがあるものです。ただし、秒には分数が含まれる場合があり、印刷出力に先行ゼロがないため、列が乱雑になります。

あなたがそれを好むなら、これが私のルーチンです:

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

これにより、出力が dd:hh:mm:ss 形式で返されます。

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

これに年を追加することも考えましたが、出力は 1 年以上安全であるため、これは読者の演習として残されています。

>>> str(datetime.timedelta(seconds=99999999))
'1157 days, 9:46:39'
于 2013-01-09T22:16:26.950 に答える
13

datetime.timedeltaのオブジェクトは 1 日以上かかりました。そこで、さらなる問題が。上記の説明はすべて、1 日未満を想定しています。Atimedeltaは実際には日、秒、マイクロ秒のタプルです。上記の説明はtd.secondsjoe が行ったように使用する必要がありますが、日数がある場合は秒の値に含まれません。

2つの日時と印刷日と時間の間に時間のスパンがあります。

span = currentdt - previousdt
print '%d,%d\n' % (span.days,span.seconds/3600)
于 2009-10-29T14:23:22.417 に答える
6

上記のジョーの例の値に従って、モジュラス算術演算子を使用します。

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

Python の整数除算はデフォルトで切り捨てられることに注意してください。より明確にしたい場合は、必要に応じて math.floor() または math.ceil() を使用してください。

于 2009-02-11T20:52:18.180 に答える
5
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
于 2013-09-29T05:21:26.497 に答える
1

この関数を確認してください - 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)
于 2016-03-03T08:34:33.867 に答える
-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)

だから:

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

戻り値:

'0:03:47'
于 2013-07-21T13:01:00.220 に答える
-13

助けてくれてありがとう。私はあなたのアイデアの多くを取り入れてまとめました。あなたの考えを教えてください。

次のように、クラスに 2 つのメソッドを追加しました。

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

私のdjangoではこれを使用しました(合計はオブジェクトであり、辞書にあります):

<td>{{ sum.0 }}</td>    
<td>{{ sum.1.hours|stringformat:"d" }}:{{ sum.1.minutes|stringformat:"#02.0d" }}</td>
于 2009-02-11T21:11:26.623 に答える