Convert seconds to compound duration: Difference between revisions

From Rosetta Code
Content added Content deleted
m (→‎Perl: and →‎Perl 6: use consistent unit abbreviation in output)
(Add Python)
Line 113: Line 113:
6000000 sec = 9 wk, 6 d, 10 hr, 40 min
6000000 sec = 9 wk, 6 d, 10 hr, 40 min
</pre>
</pre>

=={{header|Python}}==
<lang python>>>> def duration(seconds):
times= []
for dm in (60, 60, 24, 7):
seconds, m = divmod(seconds, dm)
t.append(m)
t.append(seconds)
return ', '.join('%d %s' % (num, unit)
for num, unit in zip(t[::-1], 'wk d hr min sec'.split())
if num)

>>> for seconds in [7259, 86400, 6000000]:
print("%7d sec = %s" % (seconds, duration(seconds)))

7259 sec = 2 hr, 59 sec
86400 sec = 1 d
6000000 sec = 9 wk, 6 d, 10 hr, 40 min
>>> </lang>

Revision as of 02:32, 7 June 2015

Convert seconds to compound duration is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

Write a function or program which

  • takes a positive integer representing a duration in seconds as input (e.g. 100), and
  • returns a string which shows the same duration decomposed into weeks, days, hours, minutes, and seconds as detailed below (e.g. "1 min, 40 sec").

Demonstrate that it passes the following three test-cases:

Test Cases

input number output string
7259 2 hr, 59 sec
86400 1 d
6000000 9 wk, 6 d, 10 hr, 40 min

Details

  • The following five units should be used:
    unit suffix used in output conversion
    week wk 1 week = 7 days
    day d 1 day = 24 hours
    hour hr 1 hour = 60 minutes
    minute min 1 minutes = 60 seconds
    second sec
  • However, only include quantities with non-zero values in the output (e.g. return "1 d" and not "0 wk, 1 d, 0 hr, 0 min, 0 sec").
  • Give larger units precedence over smaller ones as much as possible (e.g. return 2 min, 10 sec and not 1 min, 70 sec or 130 sec)
  • Mimic the formatting shown in the test-cases (quantities sorted from largest unit to smallest and separated by comma+space; value and unit of each quantity separated by space).


Perl

<lang perl>sub compound_duration {

   my $sec = shift;
   no warnings 'numeric';
   
   return join ', ', grep { $_ > 0 }
       int($sec/60/60/24/7)    . " wk",
       int($sec/60/60/24) % 7  . " d",
       int($sec/60/60)    % 24 . " hr",
       int($sec/60)       % 60 . " min",
       int($sec)          % 60 . " sec";

}</lang>

Demonstration: <lang perl>for (7259, 86400, 6000000) {

   printf "%7d sec  =  %s\n", $_, compound_duration($_)

}</lang>

Output:
   7259 sec  =  2 hr, 59 sec
  86400 sec  =  1 d
6000000 sec  =  9 wk, 6 d, 10 hr, 40 min

Perl 6

The built-in polymod method (which is a generalization of the divmod function known from other languages), is a perfect match for a task like this:

<lang perl6>sub compound-duration ($seconds) {

   ($seconds.polymod(60, 60, 24, 7) Z <sec min hr d wk>)\
   .grep(*[0]).reverse.join(", ")

}</lang>

Demonstration: <lang perl6>for 7259, 86400, 6000000 {

   say "{.fmt: '%7d'} sec  =  {compound-duration $_}";

}</lang>

Output:
   7259 sec  =  2 hr, 59 sec
  86400 sec  =  1 d
6000000 sec  =  9 wk, 6 d, 10 hr, 40 min

Python

<lang python>>>> def duration(seconds): times= [] for dm in (60, 60, 24, 7): seconds, m = divmod(seconds, dm) t.append(m) t.append(seconds) return ', '.join('%d %s' % (num, unit) for num, unit in zip(t[::-1], 'wk d hr min sec'.split()) if num)

>>> for seconds in [7259, 86400, 6000000]: print("%7d sec = %s" % (seconds, duration(seconds)))


  7259 sec = 2 hr, 59 sec
 86400 sec = 1 d

6000000 sec = 9 wk, 6 d, 10 hr, 40 min >>> </lang>