File Coverage

blib/lib/DateTime/Duration/Fuzzy.pm
Criterion Covered Total %
statement 31 34 91.1
branch 7 10 70.0
condition 1 3 33.3
subroutine 7 7 100.0
pod 1 1 100.0
total 47 55 85.4


line stmt bran cond sub pod time code
1             package DateTime::Duration::Fuzzy;
2              
3 1     1   18514 use strict;
  1         2  
  1         30  
4 1     1   774 use utf8;
  1         10  
  1         6  
5 1     1   1316 use DateTime;
  1         160012  
  1         36  
6 1     1   12 use Carp;
  1         1  
  1         74  
7 1     1   5 use Exporter qw(import);
  1         2  
  1         34  
8              
9 1     1   1048 use if $ENV{ARCH_64BIT}, 'integer';
  1         9  
  1         6  
10              
11             our @EXPORT_OK = qw(time_ago);
12              
13             our $VERSION = '0.06';
14              
15             my @ranges = (
16             [ -1, 'in the future' ],
17             [ 60, 'just now' ],
18             [ 900, 'a few minutes ago'], # 15*60
19             [ 3000, 'less than an hour ago'], # 50*60
20             [ 4500, 'about an hour ago'], # 75*60
21             [ 7200, 'more than an hour ago'], # 2*60*60
22             [ 21600, 'several hours ago'], # 6*60*60
23             [ 86400, 'today', sub { # 24*60*60
24             my $time = shift;
25             my $now = shift;
26             if ( $time->day < $now->day
27             or $time->month < $now->month
28             or $time->year < $now->year
29             ) {
30             return 'yesterday'
31             }
32             if ($time->hour < 5) {
33             return 'tonight'
34             }
35             if ($time->hour < 10) {
36             return 'this morning'
37             }
38             if ($time->hour < 15) {
39             return 'today'
40             }
41             if ($time->hour < 19) {
42             return 'this afternoon'
43             }
44             return 'this evening'
45             }],
46             [ 172800, 'yesterday'], # 2*24*60*60
47             [ 604800, 'this week'], # 7*24*60*60
48             [ 1209600, 'last week'], # 2*7*24*60*60
49             [ 2678400, 'this month', sub { # 31*24*60*60
50             my $time = shift;
51             my $now = shift;
52             if ($time->year == $now->year and $time->month == $now->month) {
53             return 'this month'
54             }
55             return 'last month'
56             }],
57             [ 5356800, 'last month'], # 2*31*24*60*60
58             [ 24105600, 'several months ago'], # 9*31*24*60*60
59             [ 31536000, 'about a year ago'], # 365*24*60*60
60             [ 34214400, 'last year'], # (365+31)*24*60*60
61             [ 63072000, 'more than a year ago'], # 2*365*24*60*60
62             [ 283824000, 'several years ago'], # 9*365*24*60*60
63             [ 315360000, 'about a decade ago'], # 10*365*24*60*60
64             [ 630720000, 'last decade'], # 20*365*24*60*60
65             [ 2838240000, 'several decades ago'], # 90*365*24*60*60
66             [ 3153600000, 'about a century ago'], # 100*365*24*60*60
67             [ 6307200000, 'last century'], # 200*365*24*60*60
68             [ 6622560000, 'more than a century ago'], # 210*365*24*60*60
69             [ 28382400000, 'several centuries ago'], # 900*365*24*60*60
70             [ 31536000000, 'about a millenium ago'], # 1000*365*24*60*60
71             [ 63072000000, 'more than a millenium ago'], # 2000*365*24*60*60
72             );
73            
74             sub time_ago {
75 31     31 1 33654 my ($time, $now) = @_;
76            
77 31 50 33     224 if (not defined $time or not $time->isa('DateTime')) {
78 0         0 croak('DateTime::Duration::Fuzzy::time_ago needs a DateTime object as first parameter')
79             }
80 31 50       74 if (not defined $now) {
81 0         0 $now = DateTime->now();
82             }
83 31 50       91 if (not $now->isa('DateTime')) {
84 0         0 croak('Invalid second parameter provided to DateTime::Duration::Fuzzy::time_ago; it must be a DateTime object if provided')
85             }
86            
87             # Use clones in UTC for safe date calculation
88 31         89 my $now_clone = $now->clone->set_time_zone('UTC');
89 31         4011 my $time_clone = $time->clone->set_time_zone('UTC');
90 31         3614 my $dur = $now_clone->subtract_datetime_absolute( $time_clone )->in_units('seconds');
91              
92 31         4207 foreach my $range ( @ranges ) {
93 413 100       802 if ( $dur <= $range->[0] ) {
94 30 100       71 if ( $range->[2] ) {
95 6         18 return $range->[2]->( $time_clone, $now_clone )
96             }
97 24         184 return $range->[1]
98             }
99             }
100            
101 1         7 return 'millenia ago'
102             }
103              
104             1
105              
106             __END__