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

In reply to time2string by rendler

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.