Produces nicely formated time from elapsed seconds.
This is kind of like
Formatting elapsed time, but has more options and has date units from seconds into years.
sub dhm {
my $time = shift;
my (@times, @time);
my @format = qw(m h d);
push @times, ($time / 60) % 60; # Minutes
push @times, ($time / (60 * 60)) % 24; # Hours
push @times, int($time / (24 * 60 * 60)); # Days
for my $i (0 .. $#times) {
push @time, "$times[$i]\cB$format[$i]\cB" if $times[$i] > 0;
}
return join ' ', reverse @time;
}
sub time2string {
my %defaults = (
long_format => 1,
spacing => 1,
bold => 0
);
my $time = shift;
my %args = (%defaults, @_);
my @format;
if ($args{format}) {
$args{long_format} = 1;
@format = split ' ', $args{format};
}
if (@format) {
die "error: format needs excatly 7 values.\n" unless $#format == 6
+;
} else {
if ($args{long_format} == 1) {
@format = qw(sec min hour day week month year);
} elsif ($args{long_format} == 2) {
@format = qw(second minute hour day week month year);
} elsif (!$args{format} && !$args{long_format}) {
@format = qw(s m h d w mo y);
}
}
die "error: time must only only be digits.\n" if !defined $time ||
+ $time !~ /^\-?\d+$/;
my $prefix = '';
if ($time < 0) {
$time = - $time;
$prefix = "- ";
}
my (@times, @data);
push @times, $time % 60; # Seconds
push @times, ($time / 60) % 60; # Minutes
push @times, ($time / (60 * 60)) % 24; # Hours
push @times, int($time / (24 * 60 * 60)); # Days
my $modulo = sub {
my ($days, $d) = @_;
my $return;
if ($d >= $days) {
$return = int($d / $days);
$d = $d % $days;
} else {
$return = 0;
}
return $return, $d;
};
($times[6], $times[3]) = $modulo->(365, $times[3]); # Years
($times[5], $times[3]) = $modulo->(30, $times[3]); # Months
($times[4], $times[3]) = $modulo->(7, $times[3]); # Weeks
$time = defined $prefix ? $prefix : undef;
for my $i (reverse 0 .. $#times) {
next if $times[$i] == 0;
$format[$i] .= $times[$i] > 1 && $args{long_format} && !$args{
+format} ? 's ' : ' ';
$time .= $args{spacing} ? "$times[$i] $format[$i]" : "$t
+imes[$i]$format[$i]";
}
$time =~ s#([A-Z]+)#\cB$1\cB#ig if $args{bold} == 1;
return $time;
}
example usage:
time2string(time, bold => 1) # Bold text for IRC.
9y 4mo 1w 2d 8h 13m 11s
time2string(time, long_format => 1) # Use long(er) unit names.
9 years 4 months 1 week 2 days 8 hours 13 mins 11 secs
time2string(time, long_format => 2) # Full length unit names.
9 years 4 months 1 week 2 days 8 hours 13 minutes 11 seconds
time2string(time, format => 'Sec Min Hour Day Week Month Year'); # De
+fine your own unit names.
9 Year 4 Month 1 Week 2 Day 8 Hour 13 Min 11 Sec
time2string(time, spacing => 0, format => 'Sec Min Hour Day Week Mon
+th Year'); # Turn off spacing.
9Year 4Month 1Week 2Day 8Hour 13Min 11Sec
dhm(time) # For things that don't need a lot of spiff.
391d 17h 49m