File Coverage

blib/lib/ORM/Date.pm
Criterion Covered Total %
statement 31 109 28.4
branch 2 34 5.8
condition n/a
subroutine 10 40 25.0
pod 21 25 84.0
total 64 208 30.7


line stmt bran cond sub pod time code
1             #
2             # DESCRIPTION
3             # PerlORM - Object relational mapper (ORM) for Perl. PerlORM is Perl
4             # library that implements object-relational mapping. Its features are
5             # much similar to those of Java's Hibernate library, but interface is
6             # much different and easier to use.
7             #
8             # AUTHOR
9             # Alexey V. Akimov
10             #
11             # COPYRIGHT
12             # Copyright (C) 2005-2006 Alexey V. Akimov
13             #
14             # This library is free software; you can redistribute it and/or
15             # modify it under the terms of the GNU Lesser General Public
16             # License as published by the Free Software Foundation; either
17             # version 2.1 of the License, or (at your option) any later version.
18             #
19             # This library is distributed in the hope that it will be useful,
20             # but WITHOUT ANY WARRANTY; without even the implied warranty of
21             # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22             # Lesser General Public License for more details.
23             #
24             # You should have received a copy of the GNU Lesser General Public
25             # License along with this library; if not, write to the Free Software
26             # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
27             #
28              
29             package ORM::Date;
30              
31             $VERSION=0.8;
32              
33 6     6   24384 use Carp;
  6         11  
  6         438  
34 6     6   5631 use POSIX;
  6         51611  
  6         73  
35 6     6   25555 use ORM::Datetime;
  6         14  
  6         2543  
36             use overload
37 0 0   0   0 '>' => sub { ( my $err = _check_args( @_ ) ); $err && croak $err; $_[0]->epoch > $_[1]->epoch; },
  0         0  
  0         0  
38 0 0   0   0 '<' => sub { ( my $err = _check_args( @_ ) ); $err && croak $err; $_[0]->epoch < $_[1]->epoch; },
  0         0  
  0         0  
39 0 0   0   0 '>=' => sub { ( my $err = _check_args( @_ ) ); $err && croak $err; $_[0]->epoch >= $_[1]->epoch; },
  0         0  
  0         0  
40 0 0   0   0 '<=' => sub { ( my $err = _check_args( @_ ) ); $err && croak $err; $_[0]->epoch <= $_[1]->epoch; },
  0         0  
  0         0  
41 0 0   0   0 '==' => sub { ( my $err = _check_args( @_ ) ); $err && croak $err; $_[0]->epoch == $_[1]->epoch; },
  0         0  
  0         0  
42 0 0   0   0 '!=' => sub { ( my $err = _check_args( @_ ) ); $err && croak $err; $_[0]->epoch != $_[1]->epoch; },
  0         0  
  0         0  
43 0 0   0   0 '<=>' => sub { ( my $err = _check_args( @_ ) ); $err && croak $err; $_[0]->epoch <=> $_[1]->epoch; },
  0         0  
  0         0  
44 0 0   0   0 'cmp' => sub { ( my $err = _check_args( @_ ) ); $err && croak $err; $_[0]->epoch cmp $_[1]->epoch; },
  0         0  
  0         0  
45 6     6   35 'fallback' => 1;
  6         24  
  6         100  
46              
47             my $use_local_tz = 1;
48              
49             ##
50             ## CONSTRUCTORS
51             ##
52              
53             sub new_epoch
54             {
55 128     128 1 224 my $class = shift;
56 128         201 my $epoch = shift;
57              
58 128         899 return bless { epoch=>$epoch }, $class;
59             }
60              
61             sub new
62             {
63 7     7 1 30 my $class = shift;
64 7         11 my $array = shift;
65              
66 7         435 my $time = POSIX::mktime
67             (
68             $array->[5],
69             $array->[4],
70             $array->[3],
71             $array->[2],
72             $array->[1]-1,
73             $array->[0]-1900,
74             0,0,-1
75             );
76              
77 7 50       24 unless( defined $time )
78             {
79 0         0 croak "Specified time [".join( ',',@$array )."] cannot be represented";
80             }
81              
82 7         21 $class->new_epoch( $time );
83             }
84              
85             sub new_mysql
86             {
87 0     0 1 0 my $class = shift;
88 0         0 my $str = shift;
89 0         0 my $date;
90              
91 0 0       0 if( $str =~ /^(\d{4,4})\-0*(\d+)\-0*(\d+)$/ )
    0          
92             {
93 0         0 $date = $class->new( [ $1, $2, $3, 0, 0, 0 ] );
94             }
95             elsif( $str =~ /^(\d{4,4})\-0*(\d+)\-0*(\d+)(\s+0*(\d+)\:0*(\d+)(\:0*(\d+))?)$/ )
96             {
97 0         0 $date = $class->new( [ $1, $2, $3, $5, $6, $8 ] );
98             }
99              
100 0         0 return $date;
101             }
102              
103             sub copy
104             {
105 0     0 1 0 my $class = shift;
106 0         0 my $self;
107              
108 0 0       0 if( ref $class )
109             {
110 0         0 $self = $class;
111 0         0 $class = ref $class;
112             }
113             else
114             {
115 0         0 $self = shift;
116             }
117              
118 0         0 return $class->new_epoch( $self->{epoch} );
119             }
120              
121             sub diff
122             {
123 0     0 1 0 my $self = shift;
124 0         0 my @diff = @{$_[0]};
  0         0  
125              
126 0         0 return (ref $self)->new
127             (
128             [
129             $self->year + $diff[0],
130             $self->month + $diff[1],
131             $self->mday + $diff[2],
132             $self->hour + $diff[3],
133             $self->min + $diff[4],
134             $self->sec + $diff[5],
135             ],
136             );
137             }
138              
139             sub current
140             {
141 0     0 0 0 my $class = shift;
142 0         0 my $date = $class->new_epoch( time );
143 0         0 $class->new( [$date->year,$date->month,$date->mday,0,0,0] );
144             }
145             sub earlier24h
146             {
147 0     0 0 0 my $class = shift;
148 0         0 my $date = $class->new_epoch( time-24*60*60 );
149 0         0 $class->new( [$date->year,$date->month,$date->mday,0,0,0] );
150             }
151              
152 0     0 1 0 sub date { ORM::Date->new_epoch( $_[0]->epoch ); }
153 0     0 1 0 sub datetime { ORM::Datetime->new_epoch( $_[0]->epoch ); }
154              
155             ##
156             ## OBJECT PROPERTIES
157             ##
158              
159 26     26 1 245 sub epoch { $_[0]->{epoch}; }
160 0     0 1 0 sub sec { $_[0]->_tz_time( $_[0]->epoch )->[0]; }
161 0     0 1 0 sub min { $_[0]->_tz_time( $_[0]->epoch )->[1]; }
162 0     0 1 0 sub hour { $_[0]->_tz_time( $_[0]->epoch )->[2]; }
163 0     0 1 0 sub mday { $_[0]->_tz_time( $_[0]->epoch )->[3]; }
164 0     0 1 0 sub wday { $_[0]->_tz_time( $_[0]->epoch )->[6]; }
165 0     0 1 0 sub yday { $_[0]->_tz_time( $_[0]->epoch )->[7]; }
166 0     0 1 0 sub month { $_[0]->_tz_time( $_[0]->epoch )->[4]; }
167 0     0 1 0 sub year { $_[0]->_tz_time( $_[0]->epoch )->[5]; }
168              
169             sub mysql_date
170             {
171 0     0 1 0 my $self = shift;
172 0         0 my $time = $self->_tz_time( $self->epoch );
173              
174 0         0 sprintf '%04d-%02d-%02d', $time->[5], $time->[4], $time->[3];
175             }
176              
177             sub mysql_time
178             {
179 0     0 1 0 my $self = shift;
180 0         0 my $time = $self->_tz_time( $self->epoch );
181              
182 0         0 sprintf '%02d:%02d:%02d', $time->[2], $time->[1], $time->[0];
183             }
184              
185             sub mysql_datetime
186             {
187 26     26 1 41 my $self = shift;
188 26         102 my $time = $self->_tz_time( $self->epoch );
189              
190 26         552 sprintf '%04d-%02d-%02d %02d:%02d:%02d'
191             , $time->[5], $time->[4], $time->[3]
192             , $time->[2], $time->[1], $time->[0];
193             }
194              
195             sub datetime_str
196             {
197 0     0 1 0 my $self = shift;
198              
199 0         0 scalar $self->_tz_time_str( $self->epoch );
200             }
201              
202             ##
203             ## OBJECT METHODS
204             ##
205              
206 0     0 1 0 sub set_epoch { $_[0]->{epoch} = $_[1]; }
207              
208             ##
209             ## CLASS PROPERTIES
210             ##
211              
212 1     1 0 3 sub use_local_tz { $use_local_tz = 1; }
213 0     0 0 0 sub use_utc_tz { $use_local_tz = 0; }
214              
215             ##
216             ## PROTECTED PROPERTIES
217             ##
218              
219             sub _tz_time
220             {
221 26     26   47 my $class = shift;
222 26         45 my $time = shift;
223 26 50       1395 my @time = $use_local_tz ? localtime $time : gmtime $time;
224              
225 26         57 $time[4] ++;
226 26         53 $time[5] += 1900;
227              
228 26         70 return \@time;
229             }
230              
231             sub _tz_time_str
232             {
233 0     0     my $class = shift;
234 0           my $time = shift;
235              
236 0 0         return $use_local_tz ? localtime $time : gmtime $time;
237             }
238              
239             sub _check_args
240             {
241 0 0   0     my @arg = $_[2] ? ( $_[1], $_[0] ) : @_;
242 0           my $err = undef;
243              
244 0 0         if( ! UNIVERSAL::isa( $arg[0], 'ORM::Date' ) )
    0          
245             {
246 0           $err = "First arg must be an 'ORM::Date' instance.";
247             }
248             elsif( ! UNIVERSAL::isa( $arg[1], 'ORM::Date' ) )
249             {
250 0           $err = "Second arg must be an 'ORM::Date' instance.";
251             }
252              
253 0           $err;
254             }
255              
256             1;