5
\$\begingroup\$

Given an integer number of seconds, return a string which represents in human readable format the number of days/hours/minutes/seconds that are equivalent.

from datetime import datetime, timedelta 
def GetTime(sec):
 d = datetime(1,1,1) + timedelta(seconds=sec)
 days = (d.day-1,'d',' ') if (d.day-1 > 0) else ('','','')
 hours = (d.hour, 'h', ' ') if (d.hour > 0) else ('', '', '')
 mins = (d.minute, 'm', ' ') if (d.minute > 0) else ('', '', '')
 secs = (d.second, 's', ' ') if (d.second > 0) else ('', '', '')
 time_format = days + hours + mins + secs
 format_str = '{}'*len(time_format)
 return format_str.format(*time_format)

I think there might be a better way to do the formatting to omit values that are zero instead of combining tuples and exploding them in the format string.

200_success
145k22 gold badges190 silver badges478 bronze badges
asked Jun 15, 2018 at 20:13
\$\endgroup\$

1 Answer 1

4
\$\begingroup\$

I feel like the datetime module isn't really doing much to help you. By using it, you avoid performing arithmetic and hard-coding constants 86400, 3600, and 60. However, in exchange, you end up hard-coding the accessors .day, .hour, .minute, and .second, in such a way that you have to write similar code four times, with no easy way to generalize them. Attempts at generalization are further complicated by the fact that you need d.day-1, due to the way that you have abused datetime addition as a trick to convert the timedelta object into a datetime object.

Your output includes a trailing space, which I consider to be an annoyance. One way to avoid that would be to use ' '.join(...). On the other hand, if sec is 0, then the function would return an empty string, which is also unintuitive. I would prefer 0s as output in that special case.

In my opinion, you would be no worse off doing all of the arithmetic and formatting yourself, without the use of the datetime module.

def format_seconds(sec):
 def repeatedly(f, xs, n):
 for x in xs:
 m, n = f(n, x)
 yield m
 return ' '.join(
 '{}{}'.format(n, unit)
 for n, unit in zip(
 repeatedly(divmod, [86400, 3600, 60, 1], sec),
 'dhms'
 )
 if n
 ) or '0s'
Vogel612
25.5k7 gold badges59 silver badges141 bronze badges
answered Jun 15, 2018 at 22:10
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.