Task

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.
This is detailed below (e.g., "2 hr, 59 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 minute = 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).




 
(import (scheme base)
        (scheme write)
        (srfi 1)
        (only (srfi 13) string-join))
 
(define *seconds-in-minute* 60)
(define *seconds-in-hour* (* 60 *seconds-in-minute*))
(define *seconds-in-day* (* 24 *seconds-in-hour*))
(define *seconds-in-week* (* 7 *seconds-in-day*))
 
(define (seconds->duration seconds)
  (define (format val unit)
    (if (zero? val) "" (string-append (number->string val) " " unit)))
  (let*-values (((weeks wk-remainder) (floor/ seconds *seconds-in-week*))
                ((days dy-remainder) (floor/ wk-remainder *seconds-in-day*))
                ((hours hr-remainder) (floor/ dy-remainder *seconds-in-hour*))
                ((minutes mn-remainder) (floor/ hr-remainder *seconds-in-minute*)))
               (string-join (delete ""
                                    (list (format weeks "wk") 
                                          (format days "d") 
                                          (format hours "hr") 
                                          (format minutes "min") 
                                          (format mn-remainder "sec"))
                                    string=?) ", ")))
 
(display (seconds->duration 7259)) (newline)
(display (seconds->duration 86400)) (newline)
(display (seconds->duration 6000000)) (newline)
 