Convert seconds to compound duration: Difference between revisions

From Rosetta Code
Content added Content deleted
m (→‎{{header|Perl}}: use 'printf' instead of 'print sprintf')
m (tiny clarification)
Line 1: Line 1:
{{draft task}}
{{draft task}}
Write a function or program which
Write a function or program which
* takes an integer value representing a duration in seconds as input (e.g. <code>100</code>), and
* takes a positive integer representing a duration in seconds as input (e.g. <code>100</code>), and
* returns a string which shows the same duration decomposed into weeks, days, hours, minutes, and seconds as detailed below (e.g. "<code>1 min, 40 sec</code>").
* returns a string which shows the same duration decomposed into weeks, days, hours, minutes, and seconds as detailed below (e.g. "<code>1 min, 40 sec</code>").


Line 26: Line 26:


<ul>
<ul>
<li>The following five units should be represented:
<li>The following five units should be used:
{| class="wikitable"
{| class="wikitable"
|-
|-

Revision as of 22:20, 6 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 s  =  %s\n", $_, compound_duration($_)

}</lang>

Output:
   7259 s  =  2 hr, 59 sec
  86400 s  =  1 d
6000000 s  =  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'} s  =  {compound-duration $_}";

}</lang>

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