Convert seconds to compound duration: Difference between revisions
m (→Python: Procedural: copy-paste error fixed.) |
Simple9371 (talk | contribs) (Added Batch File code) |
||
Line 66: | Line 66: | ||
__TOC__ |
__TOC__ |
||
=={{header|Batch File}}== |
|||
<lang dos>@echo off |
|||
::The Main Thing... |
|||
for %%d in (7259 86400 6000000) do call :duration %%d |
|||
exit/b 0 |
|||
::/The Main Thing. |
|||
::The Function... |
|||
:duration |
|||
set output= |
|||
set /a "wk=%1/604800,rem=%1%%604800" |
|||
if %wk% neq 0 set "output= %wk% wk," |
|||
set /a "d=%rem%/86400,rem=%rem%%%86400" |
|||
if %d% neq 0 set "output=%output% %d% d," |
|||
set /a "hr=%rem%/3600,rem=%rem%%%3600" |
|||
if %hr% neq 0 set "output=%output% %hr% hr," |
|||
set /a "min=%rem%/60,rem=%rem%%%60" |
|||
if %min% neq 0 set "output=%output% %min% min," |
|||
if %rem% neq 0 set "output=%output% %rem% sec " |
|||
if %1 gtr 0 echo %1 sec = %output:~1,-1% |
|||
goto :EOF |
|||
::/The Function.</lang> |
|||
{{Out}} |
|||
<pre> |
|||
7259 sec = 2 hr, 59 sec |
|||
86400 sec = 1 d |
|||
6000000 sec = 9 wk, 6 d, 10 hr, 40 min |
|||
</pre> |
|||
=={{header|J}}== |
=={{header|J}}== |
Revision as of 05:36, 15 June 2015
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 not1 min, 70 sec
or130 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).
Batch File
<lang dos>@echo off
- The Main Thing...
for %%d in (7259 86400 6000000) do call :duration %%d exit/b 0
- /The Main Thing.
- The Function...
- duration
set output= set /a "wk=%1/604800,rem=%1%%604800" if %wk% neq 0 set "output= %wk% wk,"
set /a "d=%rem%/86400,rem=%rem%%%86400" if %d% neq 0 set "output=%output% %d% d,"
set /a "hr=%rem%/3600,rem=%rem%%%3600" if %hr% neq 0 set "output=%output% %hr% hr,"
set /a "min=%rem%/60,rem=%rem%%%60" if %min% neq 0 set "output=%output% %min% min,"
if %rem% neq 0 set "output=%output% %rem% sec "
if %1 gtr 0 echo %1 sec = %output:~1,-1% goto :EOF
- /The Function.</lang>
- Output:
7259 sec = 2 hr, 59 sec 86400 sec = 1 d 6000000 sec = 9 wk, 6 d, 10 hr, 40 min
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>
jq
<lang jq>def seconds_to_time_string:
def nonzero(text): floor | if . > 0 then "\(.) \(text)" else empty end; if . == 0 then "0 sec" else [(./60/60/24/7 | nonzero("wk")), (./60/60/24 % 7 | nonzero("d")), (./60/60 % 24 | nonzero("hr")), (./60 % 60 | nonzero("min")), (. % 60 | nonzero("sec"))] | join(", ") end;</lang>
Examples': <lang jq>0, 7259, 86400, 6000000 | "\(.): \(seconds_to_time_string)"</lang>
- Output:
<lang sh>$ jq -r -n -f Convert_seconds_to_compound_duration.jq 0: 0 sec 7259: 2 hr, 59 sec 86400: 1 d 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
Python: Procedural
<lang python>>>> def duration(seconds): t= [] 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>
Python: Functional
<lang python>>>> def duration(seconds, _maxweeks=99999999999):
return ', '.join('%d %s' % (num, unit)
for num, unit in zip([(seconds // d) % m for d, m in ((604800, _maxweeks),
(86400, 7), (3600, 24), (60, 60), (1, 60))],
['wk', 'd', 'hr', 'min', 'sec']) 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>
REXX
<lang rexx>/* REXX ---------------------------------------------------------------
- Format seconds into a time string
- --------------------------------------------------------------------*/
Call test 7259 ,'2 hr, 59 sec' Call test 86400 ,'1 d' Call test 6000000 ,'9 wk, 6 d, 10 hr, 40 min' Exit
test:
Parse arg secs,xres res=sec2ct(secs) Say res If res<>xres Then Say '**ERROR**' Return
sec2ct: Parse Arg s /* m=s%60; s=s//60 h=m%60; m=m//60 d=h%24; h=h//24 w=d%7; d=d//7
- /
Parse Value split(s,60) with m s Parse Value split(m,60) with h m Parse Value split(h,24) with d h Parse Value split(d, 7) with w d ol= If w>0 Then ol=ol w 'wk,' If d>0 Then ol=ol d 'd,' If h>0 Then ol=ol h 'hr,' If m>0 Then ol=ol m 'min,' If s>0 Then ol=ol s 'sec' ol=strip(ol) ol=strip(ol,,',') Return ol
split: Procedure
Parse Arg what,how a=what%how b=what//how Return a b</lang>
- Output:
2 hr, 59 sec 1 d 9 wk, 6 d, 10 hr, 40 min