Convert seconds to compound duration: Difference between revisions

(improve use of variables for iteration)
(insert →‎Pascal)
Line 2,709:
9 wk, 6 d, 10 hr, 40 min
</pre>
 
=={{header|Pascal}}==
{{works with|Extended Pascal}}
<lang pascal>program convertSecondsToCompoundDuration(output);
 
const
suffixUnitWeek = 'wk';
suffixUnitDay = 'd';
suffixUnitHour = 'hr'; { Use `'h'` to be SI-compatible. }
suffixUnitMinute = 'min';
suffixUnitSecond = 'sec'; { NB: Only `'s'` is SI-approved. }
suffixSeparator = ' '; { A non-breaking space would be appropriate. }
quantitySeparator = ', ';
{ Maximum expected length of `string` “12345 wk, 6 d, 7 hr, 8 min, 9 sec” }
timeSpanPrintedMaximumLength = 4 * length(quantitySeparator) +
20 + length(suffixUnitWeek) + 1 + length(suffixUnitDay) +
2 + length(suffixUnitHour) + 2 + length(suffixUnitMinute) +
2 + length(suffixUnitSecond) + 5 * length(suffixSeparator);
{ Units of time expressed in seconds. }
minute = 60;
hour = 60 * minute;
day = 24 * hour;
week = 7 * day;
 
type
wholeNumber = 0..maxInt;
naturalNumber = 1..maxInt;
canonicalTimeSpan = record
weeks: wholeNumber;
days: 0..6;
hours: 0..23;
minutes: 0..59;
seconds: 0..59;
end;
stringFitForTimeSpan = string(timeSpanPrintedMaximumLength);
 
{
\brief turns a time span expressed in seconds into a `canonicalTimeSpan`
\param duration the non-negative duration expressed in seconds
\return a `canonicalTimeSpan` representing \param duration seconds
}
function getCanonicalTimeSpan(duration: wholeNumber): canonicalTimeSpan;
{ Perform `div`ision and update `duration`. }
function split(protected unit: naturalNumber): wholeNumber;
begin
split := duration div unit;
duration := duration mod unit
end;
var
result: canonicalTimeSpan;
begin
with result do
begin
weeks := split(week);
days := split(day);
hours := split(hour);
minutes := split(minute);
seconds := duration
end;
{ In Pascal there needs to be _exactly_ one assignment to the }
{ result variable bearing the same name as of the `function`. }
getCanonicalTimeSpan := result
end;
 
{
\brief turns a non-trivial duration into a string
\param n a positive duration expressed in seconds
\return \param n expressed in some human-readable form
}
function timeSpanString(protected n: naturalNumber): stringFitForTimeSpan;
const
qs = quantitySeparator;
var
result: stringFitForTimeSpan;
begin
with getCanonicalTimeSpan(n) do
begin
{ `:1` specifies the minimum-width. Omitting it would cause }
{ the compiler to insert a vendor-defined default, e. g. 20. }
writeStr(result, weeks:1, suffixSeparator, suffixUnitWeek);
{ For strings, `:n` specifies the _exact_ width (padded with spaces). }
writeStr(result, result:ord(weeks > 0) * length(result));
if days > 0 then
begin
writeStr(result, result, qs:ord(length(result) > 0) * length(qs),
days:1, suffixSeparator, suffixUnitDay);
end;
if hours > 0 then
begin
writeStr(result, result, qs:ord(length(result) > 0) * length(qs),
hours:1, suffixSeparator, suffixUnitHour);
end;
if minutes > 0 then
begin
writeStr(result, result, qs:ord(length(result) > 0) * length(qs),
minutes:1, suffixSeparator, suffixUnitMinute);
end;
if seconds > 0 then
begin
writeStr(result, result, qs:ord(length(result) > 0) * length(qs),
seconds:1, suffixSeparator, suffixUnitSecond);
end
end;
timeSpanString := result
end;
 
{ === MAIN ============================================================= }
begin
writeLn( 7259, ' seconds are “', timeSpanString(7259), '”');
writeLn( 86400, ' seconds are “', timeSpanString(86400), '”');
writeLn(6000000, ' seconds are “', timeSpanString(6000000), '”')
end.</lang>
{{out}}
7259 seconds are “2 hr, 59 sec”
86400 seconds are “1 d”
6000000 seconds are “9 wk, 6 d, 10 hr, 40 min”
 
=={{header|Perl}}==
149

edits