Convert seconds to compound duration: Difference between revisions

From Rosetta Code
Content added Content deleted
(add new draft task page)
 
(add Perl and Perl 6 solutions)
Line 65: Line 65:


__TOC__
__TOC__


=={{header|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) {
print sprintf "%7ds = %s\n", $_, compound_duration($_)
}</lang>

{{out}}
<pre>
7259s = 2 hr, 59 sec
86400s = 1 d
6000000s = 9 wk, 6 d, 10 hr, 40 min
</pre>

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

The built-in <code>polymod</code> method (which is a generalization of the <code>divmod</code> 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 sprintf '%7ds = %s', $_, compound-duration($_)
}</lang>

{{out}}
<pre>
7259s = 2 hr, 59 sec
86400s = 1 d
6000000s = 9 wk, 6 d, 10 hr, 40 min
</pre>

Revision as of 21:31, 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 an integer value 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 represented:
    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) {

   print sprintf "%7ds = %s\n", $_, compound_duration($_)

}</lang>

Output:
   7259s = 2 hr, 59 sec
  86400s = 1 d
6000000s = 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 sprintf '%7ds = %s', $_, compound-duration($_)

}</lang>

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