21

I have two dates and can calculate timedelta as usual.

But I want to calculate some percent with resulting timedelta:

full_time = (100/percentage) * timdelta

But it seems that it can only multiplying with interegs.

How can I use float instead of int as multiplier?

Example:

percentage     = 43.27
passed_time    = fromtimestamp(fileinfo.st_mtime) - fromtimestamp(fileinfo.st_ctime)
multiplier     = 100 / percentage   # 2.3110700254217702796394730760342
full_time      = multiplier * passed_time # BUG: here comes exception
estimated_time = full_time - passed_time

If is used int(multiplier) — accuracy suffers.

Robert Harvey
  • 178,213
  • 47
  • 333
  • 501
Крайст
  • 776
  • 1
  • 9
  • 22
  • You're right, timedelta just supports multiplication or division with intergers, but why you don't perform the math operations in sequence step by step? `full_time = passed_time * 100 / int(percentage)` – Colin O'Coal Sep 05 '12 at 09:37
  • @Colin O'Coal, because of accuracy: `2 != 2.3131`. Compare: `571 * 2 = 1142` (**19**,03(3) minutes); `571 * 2.3131 = 1320,7801` (**22**,0130016(6) minutes). Difference is about **3 minutes** (!) – Крайст Sep 05 '12 at 11:38

2 Answers2

28

You can convert to total seconds and back again:

full_time = timedelta(seconds=multiplier * passed_time.total_seconds())

timedelta.total_seconds is available from Python 2.7; on earlier versions use

def timedelta_total_seconds(td):
    return (td.microseconds + (td.seconds + td.days * 24 * 3600) * 10**6) / float(10**6)
ecatmur
  • 152,476
  • 27
  • 293
  • 366
3

You could use total_seconds():

datetime.timedelta(seconds=datetime.timedelta(minutes=42).total_seconds() * 0.8)
# => datetime.timedelta(0, 2016)