# tests conversion of epoch time to human-readable date format, using
# Local::Utils::date_relative() and blog entry:
# http://blogs.perl.org/users/chansen/2015/07/simple-and-efficient-formatting-of-relative-datetime-durations-using-timemoment.html
use 5.24.0;
use Local::Utils;
use Test::More 0.88;
use Term::ANSIColor qw(:constants);
sub YEAR () { 365.2425 }
sub MONTH () { YEAR / 12 }
sub DAY () { 1 }
sub HOUR () { DAY / 24 }
sub MINUTE () { HOUR / 60 }
sub SECOND () { MINUTE / 60 }
my @tests = (
[ SECOND * 10, 'a few seconds ago' ],
[ MINUTE * 1, 'a minute ago' ],
[ SECOND * 75, 'a minute ago' ],
[ MINUTE * 30, '30 minutes ago' ],
[ HOUR * 1, 'an hour ago' ],
[ HOUR * 2, '2 hours ago' ],
[ DAY * 1, 'a day ago' ],
[ DAY * 20, '20 days ago' ],
[ MONTH * 1, 'a month ago' ],
[ MONTH * 2, '2 months ago' ],
[ MONTH * 13, 'a year ago' ],
[ YEAR * 1, 'a year ago' ],
[ YEAR * 2, '2 years ago' ],
[ YEAR * 10, '10 years ago' ],
[ YEAR * 100, '100 years ago' ],
);
my $now = Time::Moment->now;
for my $test (@tests) {
my ($duration, $expected) = @$test; # say $duration;
my $tm = Time::Moment->from_mjd($now->mjd - $duration);
is(ago($tm), $expected, "$tm ($expected : $duration)");
# adjust $duration back to seconds to match epoch time expected by Local::Utils::relative_date:
my $seconds = $duration * 60 * 60 * 24;
# Local::Utils::date_relative output of same duration input:
say "\tLocal::Utils::date_relative says "
. BRIGHT_RED, Local::Utils::date_relative( DateTime->now->epoch - $seconds), RESET;
}
done_testing();
sub ago {
@_ == 1 or Carp::croak(q/Usage: ago(moment)/);
my ($moment) = @_;
($now->compare($moment) >= 0)
or Carp::croak(q/Given moment is in the future/);
my $d = $now->mjd - $moment->mjd;
if ($d < 0.75 * DAY) {
if ($d < 0.75 * MINUTE) {
return 'a few seconds ago';
}
elsif ($d < 1.5 * MINUTE) {
return 'a minute ago';
}
elsif ($d < 0.75 * HOUR) {
return sprintf '%d minutes ago', $d / MINUTE + 0.5;
}
elsif ($d < 1.5 * HOUR) {
return 'an hour ago';
}
else {
return sprintf '%d hours ago', $d / HOUR + 0.5;
}
}
else {
if ($d < 1.5 * DAY) {
return 'a day ago';
}
elsif ($d < 0.75 * MONTH) {
return sprintf '%d days ago', $d / DAY + 0.5;
}
elsif ($d < 1.5 * MONTH) {
return 'a month ago';
}
elsif ($d < 0.75 * YEAR) {
return sprintf '%d months ago', $d / MONTH + 0.5;
}
elsif ($d < 1.5 * YEAR) {
return 'a year ago';
}
else {
return sprintf '%d years ago', $d / YEAR + 0.5;
}
}
}