Convert seconds to compound duration: Difference between revisions

From Rosetta Code
Content added Content deleted
(Add Python)
(J)
Line 66: Line 66:
__TOC__
__TOC__



=={{header|J}}==

Implementation:

<lang J>fmtsecs=:3 :0
seq=. 0 7 24 60 60#:y
}:;:inv,(0~:seq)#(8!:0 seq),.<;.2'wk,d,hr,min,sec,'
)</lang>

Task examples:

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


=={{header|Perl}}==
=={{header|Perl}}==

Revision as of 02:33, 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).


J

Implementation:

<lang J>fmtsecs=:3 :0

 seq=. 0 7 24 60 60#:y
 }:;:inv,(0~:seq)#(8!:0 seq),.<;.2'wk,d,hr,min,sec,'

)</lang>

Task examples:

<lang J> fmtsecs 7259 2 hr, 59 sec

  fmtsecs 86400

1 d

  fmtsecs 6000000

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

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>