4

I'm trying to code a Python script for 'Enter the number of Seconds' and get results in weeks, days, hours, minutes and seconds. Here is what I have, but I am not getting the correct answers. What am I doing wrong?

seconds = raw_input("Enter the number of seconds:")
seconds = int(seconds)

minutes = seconds/60

seconds = seconds % 60

hours = minutes/60
hours = seconds/3600

minutes = minutes % 60

days = hours/24
days = minutes/1440
days = seconds/86400

hours = hours % 60
hours = minutes % 60
hours = seconds % 3600

weeks = days/7
weeks = hours/168
weeks = minutes/10080
weeks = seconds/604800

days = days % 1
days = hours % 24
days = minutes % 1440
days = seconds % 86400

weeks = weeks % 1
weeks = days % 7
weeks = hours % 168
weeks = minutes % 10080
weeks = seconds % 604800

print weeks, 'weeks', days, 'days', hours, 'hours', minutes, 'minutes', seconds, 'seconds'
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
sjud9227
  • 49
  • 2
  • 2
  • 6

3 Answers3

10

Just from the basic conversion principles:

weeks = seconds / (7*24*60*60)
days = seconds / (24*60*60) - 7*weeks
hours = seconds / (60*60) - 7*24*weeks - 24*days
minutes = seconds / 60 - 7*24*60*weeks - 24*60*days - 60*hours
seconds = seconds - 7*24*60*60*weeks - 24*60*60*days - 60*60*hours - 60*minutes

A bit of a less noisy way of doing the same thing:

weeks = seconds / (7*24*60*60)
seconds -= weeks*7*24*60*60
days = seconds / (24*60*60)
seconds -= days*24*60*60
hours = seconds / (60*60)
seconds -= hours*60*60
minutes = seconds / 60
seconds -= minutes *60

A cleaner version of again the same thing with divmod function which returns both division result and remainder in a tuple (division, remainder):

weeks, seconds = divmod(seconds, 7*24*60*60)
days, seconds = divmod(seconds, 24*60*60)
hours, seconds = divmod(seconds, 60*60)
minutes, seconds = divmod(seconds, 60)

Basically, this solution is closest to your attempt since this is what divmod does:

weeks, seconds = divmod(seconds, 7*24*60*60)

equivalent to

weeks = seconds / (7*24*60*60)
seconds = seconds % (7*24*60*60)

Here we are essentially finding the number of whole weeks in our time and keeping what is left after these weeks are removed.


And also you can go from the other end to make it even prettier:

minutes, seconds = divmod(seconds, 60)
hours, minutes = divmod(minutes, 60)
days, hours = divmod(hours, 24)
weeks, days = divmod(days, 7)

The idea behind this is that the number of seconds in your answer is the remainder after dividing them in minutes; minutes are the remainder of dividing all minutes into hours etc... This version is better because you can easily adjust it to months, years, etc...

sashkello
  • 17,306
  • 24
  • 81
  • 109
  • That was fast, thank you! Quick question (prob a stupid one)....Why is there no need for an %? Are the - a subtraction sign? So, Minutes is seconds/60 -(minus 7*24*60*weeks) -(minus 24*60*days)?? Again, very new. – sjud9227 Jan 24 '14 at 03:27
  • @user3230374: `-` is subtraction. The modulo operation is being calculated through the mathematical identity `x % y == x - (x/y)*y`. Personally, I would have used `%` or `divmod`, but it's inconsequential. – user2357112 Jan 24 '14 at 03:35
  • Awesome, thanks for all the help! One more question...What does the -= do? How does that differ from just an = – sjud9227 Jan 24 '14 at 03:53
  • x -= 1 is equivalent to x = x - 1; x += 1 is equivalent to x = x + 1. – sashkello Jan 24 '14 at 03:56
2

Using Python's datetime timedeltas with support for milliseconds or microseconds.

import datetime
def convert(sec): 
    td = datetime.timedelta(seconds=sec, microseconds=sec-int(sec)) 
    return td.days/7, (td.days/7)%7, td.seconds/3600, (td.seconds/60)%60, td.seconds%60, td.microseconds, td.microseconds/1000

seconds = 8*24*60*60 + 21627.123  # 8 days, 6 hours (21600 seconds), 27.123 seconds
w, d, h, m, s, us, ms = convert(seconds)
print '{}s / {}w {}d {}h {}m {}s {}us {}ms'.format(seconds,w,d,h,m,s,us,ms)

712827.123s / 1w 1d 6h 0m 27s 123000us 123ms
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Bill Gale
  • 1,238
  • 1
  • 14
  • 14
0
def humanize_duration(amount, units='s'):
INTERVALS = [(lambda mlsec:divmod(mlsec, 1000), 'ms'),
             (lambda seconds:divmod(seconds, 60), 's'),
             (lambda minutes:divmod(minutes, 60), 'm'),
             (lambda hours:divmod(hours, 24), 'h'),
             (lambda days:divmod(days, 7), 'D'),
             (lambda weeks:divmod(weeks, 4), 'W'),
             (lambda years:divmod(years, 12), 'M'),
             (lambda decades:divmod(decades, 10), 'Y')]

for index_start, (interval, unit) in enumerate(INTERVALS):
    if unit == units:
        break

amount_abrev = []
last_index = 0
amount_temp = amount
for index, (formula, abrev) in enumerate(INTERVALS[index_start: len(INTERVALS)]):
    divmod_result = formula(amount_temp)
    amount_temp = divmod_result[0]
    amount_abrev.append((divmod_result[1], abrev))
    if divmod_result[1] > 0:
        last_index = index
amount_abrev_partial = amount_abrev[0: last_index + 1]
amount_abrev_partial.reverse()

final_string = ''
for amount, abrev in amount_abrev_partial:
    final_string += str(amount) + abrev + ' '
return final_string