I wasn't able to find such code a while back, so I wrote these two routines. The second sub uses the first and does what you are looking for.
#-----------------------------------------------------------
# format_seconds($seconds)
# Converts seconds into days, hours, minutes, seconds
# Returns an array in list context, else a string.
#-----------------------------------------------------------
sub format_seconds {
my $tsecs = shift;
use integer;
my $secs = $tsecs % 60;
my $tmins = $tsecs / 60;
my $mins = $tmins % 60;
my $thrs = $tmins / 60;
my $hrs = $thrs % 24;
my $days = $thrs / 24;
if (wantarray) {
return ($days, $hrs, $mins, $secs);
}
my $age = "";
$age .= $days . "d " if $days || $age;
$age .= $hrs . "h " if $hrs || $age;
$age .= $mins . "m " if $mins || $age;
$age .= $secs . "s " if $secs || $age;
$age =~ s/ $//;
return $age;
}
#-----------------------------------------------------------
# format_delta_min ($seconds)
# Converts seconds into days, hours, minutes, seconds
# to the two most significant time units.
#-----------------------------------------------------------
sub format_delta_min {
my $tsecs = shift;
my ($days, $hrs, $mins, $secs) = format_seconds $tsecs;
# show days and hours, or hours and minutes,
# or minutes and seconds or just seconds
my $age = "";
if ($days) {
$age = $days . "d " . $hrs . "h";
}
elsif ($hrs) {
$age = $hrs . "h " . $mins . "m";
}
elsif ($mins) {
$age = $mins . "m " . $secs . "s";
}
elsif ($secs) {
$age = $secs . "s";
}
return $age;
}