File Coverage

blib/lib/Time/Fuzzy.pm
Criterion Covered Total %
statement 43 43 100.0
branch 4 4 100.0
condition 17 21 80.9
subroutine 13 13 100.0
pod 3 3 100.0
total 80 84 95.2


line stmt bran cond sub pod time code
1             #
2             # This file is part of Time::Fuzzy
3             # Copyright (c) 2007 Jerome Quelin, all rights reserved.
4             #
5             # This program is free software; you can redistribute it and/or modify
6             # it under the same terms as Perl itself.
7             #
8              
9             package Time::Fuzzy;
10              
11 4     4   145309 use warnings;
  4         9  
  4         247  
12 4     4   23 use strict;
  4         7  
  4         219  
13              
14 4     4   5383 use Class::Accessor::Fast;
  4         30458  
  4         342  
15 4     4   7350 use DateTime;
  4         1139927  
  4         142  
16 4     4   41 use DateTime::Duration;
  4         5  
  4         96  
17              
18 4     4   19 use base qw[ Exporter Class::Accessor::Fast ];
  4         7  
  4         2225  
19             our @EXPORT = qw[ fuzzy ];
20             __PACKAGE__->mk_accessors( qw[ dt fuzziness ] );
21              
22             our $VERSION = '0.36';
23             our $FUZZINESS = 'medium';
24              
25             #--
26             # private vars
27              
28             # - for high fuzziness
29             my %weektime = ( # define the periods of the week
30             'start of week' => [ 1 ],
31             'middle of week' => [ 2..4 ],
32             'end of week' => [ 5 ],
33             'week-end!' => [ 6,7 ],
34             );
35             my @weektime; # a 7-slots array, one for each days
36             { # init @weektime by walking %weektime
37             foreach my $wt ( keys %weektime ) {
38             my $days = $weektime{$wt};
39             $weektime[$_] = $wt for @$days;
40             }
41             }
42              
43             # - for medium fuzziness
44             my %daytime = ( # define the periods of the day
45             'night' => [ 0, 1, 2, 3, 4 ],
46             'early morning' => [ 5, 6, 7 ],
47             'morning' => [ 8, 9, 10 ],
48             'noon' => [ 11, 12, 13 ],
49             'afternoon' => [ 14, 15, 16, 17, 18 ],
50             'evening' => [ 19, 20, 21 ],
51             'late evening' => [ 22, 23 ],
52             );
53             my @daytime; # a 24-slots array, one for each hour
54             { # init @daytime by walking %daytime
55             foreach my $dt ( keys %daytime ) {
56             my $hours = $daytime{$dt};
57             $daytime[$_] = $dt for @$hours;
58             }
59             }
60              
61             # - for low fuzziness
62             my @hourtime = ( # defining the periods of the hour
63             "%s o'clock", 'five past %s', 'ten past %s',
64             'quarter past %s', 'twenty past %s', 'twenty five past %s',
65             'half past %s', 'twenty five to %2$s', 'twenty to %2$s',
66             'quarter to %2$s', 'ten to %2$s', 'five to %2$s',
67             q{%2$s o'clock}, # needed for 58-59
68             );
69             my @hours = (
70             'midnight',
71             qw[ one two three four five six seven eight nine ten eleven noon ],
72             qw[ one two three four five six seven eight nine ten eleven midnight ],
73             );
74              
75              
76             #--
77             # public subs
78              
79             sub fuzzy {
80 39   66 39 1 28123 my $dt = $_[0] || DateTime->now( time_zone=>'local' );
81 39         7394 my %fuzzysub = (
82             low => \&_fuzzy_low,
83             medium => \&_fuzzy_medium,
84             high => \&_fuzzy_high,
85             );
86 39         122 return $fuzzysub{$FUZZINESS}->($dt);
87             }
88              
89              
90             #--
91             # public methods
92              
93             sub new {
94 1     1 1 596 my $pkg = shift;
95 1         7 my %params = (
96             dt => DateTime->now( time_zone=>'local' ),
97             fuzziness => $FUZZINESS,
98             @_,
99             );
100 1         5146 return bless \%params, $pkg;
101             }
102              
103 4     4   25 use overload '""' => \&as_str;
  4         8  
  4         44  
104             sub as_str {
105 3     3 1 1741 my ($self) = @_;
106 3         21 my %fuzzysub = (
107             low => \&_fuzzy_low,
108             medium => \&_fuzzy_medium,
109             high => \&_fuzzy_high,
110             );
111 3         12 return $fuzzysub{$self->fuzziness}->($self->dt);
112             }
113              
114              
115             #--
116             # private subs
117              
118             #
119             # my $fuz = _fuzzy_low($dt)
120             #
121             # Return a fuzzy time defined by $dt. The fuzziness is a bit low, that
122             # is, 5 minutes in this case.
123             #
124             sub _fuzzy_low {
125 7     7   16 my ($dt1) = @_;
126              
127 7         24 my $sector = int( ($dt1->minute + 2) / 5 );
128 7         53 my $hour1 = $hours[$dt1->hour];
129            
130             # compute next hour, for 2nd half of the hour.
131 7         59 my $dt2 = $dt1 + DateTime::Duration->new(hours=>1);
132 7         4315 my $hour2 = $hours[$dt2->hour];
133              
134             # midnight or noon don't need o'clock appended.
135 7 100 100     79 return $hour1
      100        
      66        
136             if ($sector==0 && $dt1->hour==0) # 0:01
137             || ($sector==0 && $dt1->hour==12); # 12:02
138 5 100 100     81 return $hour2
      66        
      66        
139             if ($sector==12 && $dt1->hour==23) # 23:58
140             || ($sector==12 && $dt1->hour==11); # 11:59
141              
142             # compute fuzzy.
143 3         14 my $fuzzy = sprintf $hourtime[$sector], $hour1, $hour2;
144 3         58 return $fuzzy;
145             }
146              
147              
148             #
149             # my $fuz = _fuzzy_medium($dt)
150             #
151             # Return a fuzzy time defined by $dt. The fuzziness is medium, that
152             # is, around 3 hours in this case.
153             #
154             sub _fuzzy_medium {
155 26     26   49 my ($dt) = @_;
156 26         73 return $daytime[$dt->hour];
157             }
158              
159              
160             #
161             # my $fuz = _fuzzy_high($dt)
162             #
163             # Return a fuzzy time defined by $dt. The fuzziness is high, that
164             # is, around the day in this case.
165             #
166             sub _fuzzy_high {
167 9     9   24 my ($dt) = @_;
168 9         30 return $weektime[$dt->dow];
169             }
170              
171              
172             1;
173             __END__