Ответ Shawn Chin - хороший, но одна проблема заключается в том, что если вы пропустите определенный элемент в своем формате (как в его втором примере, который имеет только часы и минуты, а не дни или секунды), тогда это время исчезает от вашего результата. Вы можете изменить его, чтобы исправить эту проблему и получить более точные результаты, обработав только те ключевые слова, которые действительно отображаются в строке формата.
class DeltaTemplate(Template):
delimiter = '%'
def strfdelta(tdelta, fmt):
d = {}
l = {'D': 86400, 'H': 3600, 'M': 60, 'S': 1}
rem = int(tdelta.total_seconds())
for k in ( 'D', 'H', 'M', 'S' ):
if "%{}".format(k) in fmt:
d[k], rem = divmod(rem, l[k])
t = DeltaTemplate(fmt)
return t.substitute(**d)
Использование:
>>> print strfdelta(delta_obj, "%D days %H:%M:%S")
1 days 20:18:12
>>> print strfdelta(delta_obj, "%H hours and %M to go")
44 hours and 18 to go
Это негибкий о форматировании, так как вы не можете применять строки преобразования и завершаться такими уродливыми вещами, как это:
>>> delta_obj = timedelta(minutes=5, seconds=2)
>>> print strfdelta(delta_obj, "%H:%M:%S")
0:5:2
Однако вы можете применить тот же подход и применить его к string.Formatter вместо строки .Template и получить что-то гораздо лучше.
from string import Formatter
def strfdelta(tdelta, fmt):
f = Formatter()
d = {}
l = {'D': 86400, 'H': 3600, 'M': 60, 'S': 1}
k = map( lambda x: x[1], list(f.parse(fmt)))
rem = int(tdelta.total_seconds())
for i in ('D', 'H', 'M', 'S'):
if i in k and i in l.keys():
d[i], rem = divmod(rem, l[i])
return f.format(fmt, **d)
Использование:
>>> delta_obj = timedelta(days=1, hours=20, minutes=18, seconds=12)
>>> print strfdelta(delta_obj, "{D} days {H}:{M}:{S}")
1 days 20:18:12
>>> print strfdelta(delta_obj, "{H} hours and {M} to go")
44 hours and 18 to go
>>> delta_obj = timedelta(minutes=5, seconds=2)
>>> print strfdelta(delta_obj, "{H:02}h{M:02}m{S:02}s")
00h05m02s
>>> print strfdelta(delta_obj, "{H:02}:{M:02}:{S:02}")
00:05:02
К сожалению, Ваши пользователи должны будут повторно выполнить setup.exe, чтобы проверить и установить все новые предпосылки, которые Вы добавили.
Приложения, развернутые с помощью ClickOnce только, проверяют на обновления приложения (если включено), не предпосылки, поскольку это - задание bootstrapper для проверки, все зависимости установлены, прежде чем приложение установлено.
Я нашел это на сайте Microsoft:
Setup.exe (bootstrapper) ответственен за установку всех зависимостей перед Вашим выполнением приложения. Этот bootstrapper работает как отдельный процесс, который независим от механизма исполнения ClickOnce.
HAdes корректен. Однако, пока Ваше приложение может запуститься без новой предпосылки, у Вас есть опция проверки его в коде.
Я имел ту же самую ситуацию с Crystal Reports и закончил написание кода, чтобы проверить, было ли это установлено, загрузите файлы установки и выполните его в фоновом режиме. Определенно боль, но конечный результат работала хорошо.