File Coverage

blib/lib/Time/C.pm
Criterion Covered Total %
statement 91 98 92.8
branch 2 4 50.0
condition 6 15 40.0
subroutine 29 32 90.6
pod 5 5 100.0
total 133 154 86.3


line stmt bran cond sub pod time code
1 2     2   45558 use strict;
  2         4  
  2         58  
2 2     2   8 use warnings;
  2         3  
  2         105  
3             package Time::C;
4             $Time::C::VERSION = '0.001';
5             # ABSTRACT: Convenient time manipulation.
6              
7 2     2   9 use Carp qw/ croak /;
  2         7  
  2         190  
8             use overload (
9 1     1   3 '""' => sub { shift->string },
10 2         17 fallback => 1,
11 2     2   2369 );
  2         1838  
12 2     2   724 use Time::Moment;
  2         1454  
  2         45  
13 2     2   951 use Sentinel;
  2         1689  
  2         106  
14              
15 2     2   780 use Time::C::Val;
  2         3  
  2         1067  
16              
17             sub _build {
18 10     10   26 my $meth = shift;
19 10         9 my $class = shift;
20 10         478 my $tm = Time::Moment->$meth(@_);
21              
22 10         38 bless { tm => $tm }, $class;
23             }
24              
25             my @accessors = (qw/
26             year month week hour minute second millisecond microsecond nanosecond /);
27             my @new_accs = (qw/ epoch jd mjd rd /);
28             my @day_accs = (qw/ day_of_month day_of_week day_of_year day_of_quarter /);
29              
30             sub _acc :lvalue {
31 32     32   33 my $val = shift;
32 32         27 my $self = shift;
33 32         45 $self->_apply();
34              
35             $self->{$val} //= Time::C::Val->new(
36 32   66     191 val => $self->{tm}->$val(), self => $self, acc => $val);
37             sentinel value => $self->{$val}, set =>
38 32     23   205 sub { $self->{$val} = $_[0]; $self->_apply() };
  23         32  
  23         53  
39             }
40              
41             sub _new_acc :lvalue {
42 4     4   4 my $val = shift;
43 4         5 my $self = shift;
44 4         6 $self->_apply();
45              
46 4         18 $self->{$val} = $self->{tm}->$val();
47             sentinel value => $self->{$val}, set =>
48 4     0   27 sub { $self->{$val} = $_[0]; $self->_apply() };
  0         0  
  0         0  
49             }
50              
51             sub _day_acc :lvalue {
52 25     25   24 my $val = shift;
53 25         20 my $self = shift;
54 25         40 $self->_apply();
55              
56             $self->{$val} //= Time::C::Val->new(
57 25   33     153 val => $self->{tm}->$val(), self => $self, acc => $val, meth => 'day');
58             sentinel value => $self->{$val}, set =>
59 25     20   165 sub { $self->{$val} = $_[0]; $self->_apply() };
  20         26  
  20         44  
60             }
61              
62             sub _apply {
63 179     179   128 my $self = shift;
64 179         208 foreach my $acc (grep { exists $self->{$_} }
  2685         2555  
65             @accessors, @day_accs, 'offset', 'quarter') {
66 65         103 my $meth = "with_$acc";
67 65 50       65 eval {
68 65         241 $self->{tm} = $self->{tm}->$meth(delete $self->{$acc});
69 65         185 1;
70             } or croak "$@";
71             }
72 179         163 foreach my $acc (grep { exists $self->{$_} } @new_accs, 'string') {
  895         997  
73 55         74 my $meth = "from_$acc";
74 55 50       59 eval {
75 55         292 $self->{tm} = Time::Moment->$meth(delete $self->{$acc});
76 55         180 1;
77             } or croak "$@";
78             }
79             }
80              
81             # constructors
82              
83             for my $const (qw/ new now now_utc from_epoch from_object from_string from_rd
84             from_jd from_mjd /) {
85 2     2   11 no strict 'refs';
  2         4  
  2         128  
86 10     10   41 *$const = sub { _build($const, @_); };
87             }
88              
89             # accessors
90              
91             for my $acc (@accessors) {
92 2     2   8 no strict 'refs';
  2         2  
  2         137  
93 32     32   71 *$acc = sub :lvalue { _acc($acc, @_); };
94             }
95              
96             for my $acc (@new_accs) {
97 2     2   9 no strict 'refs';
  2         15  
  2         125  
98 4     4   11 *$acc = sub :lvalue { _new_acc($acc, @_); };
99             }
100              
101             for my $acc (@day_accs) {
102 2     2   7 no strict 'refs';
  2         3  
  2         585  
103 25     25   49 *$acc = sub :lvalue { _day_acc($acc, @_); };
104             }
105              
106             sub string :lvalue {
107 61     61 1 3745 my $self = shift;
108 61         83 $self->_apply();
109              
110 61   33     582 $self->{string} //= "$self->{tm}";
111             sentinel value => $self->{string}, set =>
112 61     0   439 sub { $self->{string} = $_[0]; $self->_apply() };
  0         0  
  0         0  
113             }
114              
115             sub tm :lvalue {
116 0     0 1 0 my $self = shift;
117 0         0 $self->_apply();
118              
119 0         0 $self->{tm};
120             }
121              
122             sub day :lvalue {
123 9     9 1 28 shift->day_of_month();
124             }
125              
126             sub offset :lvalue {
127 2     2 1 4 my $self = shift;
128 2         7 $self->_apply();
129              
130 2   33     15 $self->{offset} //= $self->{tm}->offset();
131             sentinel value => $self->{offset}, set =>
132 2     1   18 sub { $self->{offset} = $_[0]; $self->_apply() };
  1         1  
  1         3  
133             }
134              
135             sub quarter :lvalue {
136 6     6 1 8 my $self = shift;
137 6         10 $self->_apply();
138              
139 6   33     29 $self->{quarter} //= $self->{tm}->quarter();
140             sentinel value => $self->{quarter}, set =>
141 6     5   33 sub { $self->{quarter} = $_[0]; $self->_apply() };
  5         6  
  5         6  
142             }
143              
144             1;
145              
146             __END__