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).




using System;
using System.Collections.Generic;
using System.Linq;
 
namespace ConvertSecondsToCompoundDuration
{
  class Program
  {
    static void Main( string[] args )
    {
      foreach ( string arg in args )
      {
        int duration ;
        bool isValid = int.TryParse( arg , out duration ) ;
 
        if ( !isValid     ) { Console.Error.WriteLine( "ERROR: Not an integer: {0}"           , arg ) ; }
        if ( duration < 0 ) { Console.Error.WriteLine( "ERROR: duration must be non-negative" , arg ) ; }
 
        Console.WriteLine();
        Console.WriteLine( "{0:#,##0} seconds ==> {1}" , duration , FormatAsDuration(duration) ) ;
 
      }
    }
 
    private static string FormatAsDuration( int duration )
    {
      if ( duration < 0 ) throw new ArgumentOutOfRangeException("duration") ;
      return string.Join( ", " , GetDurationParts(duration)  ) ;
    }
 
    private static IEnumerable<string> GetDurationParts( int duration )
    {
      var parts = new[]
      {
        new { Name="wk" , Length = 7*24*60*60*1 , } ,
        new { Name="d"  , Length =   24*60*60*1 , } ,
        new { Name="h"  , Length =      60*60*1 , } ,
        new { Name="m"  , Length =         60*1 , } ,
        new { Name="s"  , Length =            1 , } ,
      } ;
 
      foreach ( var part in parts )
      {
        int n = Math.DivRem( duration , part.Length , out duration ) ;
        if ( n > 0 ) yield return string.Format( "{0} {1}" , n , part.Name ) ;
      }
 
    }
 
  }
 
}