Вышеупомянутые ответы, похоже, не обрабатывают значения negative timedelta (как получено, например, pytz для часовых поясов «слева» от UTC). Как для документации , объекты timedelta нормализованы, а отрицательный timedelta представлен отрицательным атрибутом экземпляра day
. Из документации:
Обратите внимание, что сначала нормализация отрицательных значений может быть неожиданным.
blockquote>и что
Строковые представления объектов timedelta нормированы аналогично их внутреннему представлению. Это приводит к несколько необычным результатам для отрицательных timedeltas.
blockquote>Например:
>>> td = timedelta(seconds=-30) >>> str(td) '-1 day, 23:59:30' >>> repr(td) 'datetime.timedelta(-1, 86370)'
Учитывая этот пример timedelta, принятый ответ Shawn Chin и ответ return
'23:59:30'
и mpounsett'-1:59:30'
.Я думаю, чтобы напечатать как отрицательные, так и положительные timedeltas в более читаемым образом, мы должны явно обрабатывать знак и абсолютное значение объекта часового пояса:
def strfdelta(td, fmt): # Get the timedelta’s sign and absolute number of seconds. sign = "-" if td.days < 0 else "+" secs = abs(td).total_seconds() # Break the seconds into more readable quantities. days, rem = divmod(secs, 86400) # seconds per day: 24 * 60 * 60 hours, rem = divmod(rem, 3600) # seconds per hour: 60 * 60 mins, secs = divmod(rem, 60) # Format (as per above answers) and return the result string. t = DeltaTemplate(fmt) return t.substitute( s=sign, D="{:d}".format(int(days)), H="{:02d}".format(int(hours)), M="{:02d}".format(int(mins)), S="{:02d}".format(int(secs)), )
Эта функция возвращает более читаемое строковое представление:
>>> strfdelta(td, "%s%H:%M:%S") # Note that %s refers to the timedelta’s sign. '-00:00:30' >>> strfdelta(timedelta(days=-1), "%s%D %H:%M:%S") '-1 00:00:00' >>> strfdelta(timedelta(days=-1, minutes=5), "%s%D %H:%M:%S") '-0 23:55:00' >>> strfdelta(timedelta(days=-1, minutes=-5), "%s%D %H:%M:%S") '-1 00:05:00'
... или в более практическом контексте часовых поясов:
>>> import pytz >>> import datetime >>> td = pytz.timezone("Canada/Newfoundland").utcoffset(datetime.datetime.now()) >>> td datetime.timedelta(-1, 77400) >>> strfdelta(td, fmt="%s%H:%M") '-02:30' >>> td = pytz.timezone("Australia/Eucla").utcoffset(datetime.datetime.now()) >>> td datetime.timedelta(0, 31500) >>> strfdelta(td, fmt="%s%H:%M") '+08:45'