File | /project/perl/lib/Class/Date.pm |
Statements Executed | 233 |
Statement Execution Time | 38.8ms |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
6 | 4 | 1 | 419µs | 545µs | _set_tz | Class::Date::
1 | 1 | 1 | 247µs | 1.93ms | new_from_array | Class::Date::
1 | 1 | 1 | 205µs | 1.68ms | _recalc_from_struct | Class::Date::
2 | 2 | 1 | 187µs | 1.30ms | _set_temp_tz | Class::Date::
7 | 2 | 2 | 173µs | 173µs | tzset_xs (xsub) | Class::Date::
2 | 2 | 1 | 137µs | 137µs | _check_sum | Class::Date::
1 | 1 | 1 | 99µs | 2.07ms | new_from_scalar_internal | Class::Date::
1 | 1 | 1 | 95µs | 2.25ms | new | Class::Date::
1 | 1 | 1 | 54µs | 2.13ms | new_from_scalar | Class::Date::
2 | 2 | 1 | 52µs | 68µs | local_timezone | Class::Date::
3 | 1 | 2 | 43µs | 43µs | CORE:match (opcode) | Class::Date::
1 | 1 | 1 | 40µs | 2.29ms | date | Class::Date::
1 | 1 | 1 | 38µs | 303µs | _recalc_from_epoch | Class::Date::
1 | 1 | 1 | 32µs | 711µs | __ANON__[:290] | Class::Date::
1 | 1 | 1 | 25µs | 25µs | __ANON__[:308] | Class::Date::
1 | 1 | 2 | 21µs | 21µs | bootstrap (xsub) | Class::Date::
2 | 1 | 2 | 16µs | 16µs | tzname_xs (xsub) | Class::Date::
0 | 0 | 0 | 0s | 0s | BEGIN | Class::Date::
0 | 0 | 0 | 0s | 0s | AUTOLOAD | Class::Date::Invalid::
0 | 0 | 0 | 0s | 0s | BEGIN | Class::Date::Invalid::
0 | 0 | 0 | 0s | 0s | compare | Class::Date::Invalid::
0 | 0 | 0 | 0s | 0s | empty | Class::Date::Invalid::
0 | 0 | 0 | 0s | 0s | errmsg | Class::Date::Invalid::
0 | 0 | 0 | 0s | 0s | error | Class::Date::Invalid::
0 | 0 | 0 | 0s | 0s | true | Class::Date::Invalid::
0 | 0 | 0 | 0s | 0s | zero | Class::Date::Invalid::
0 | 0 | 0 | 0s | 0s | BEGIN | Class::Date::Rel::
0 | 0 | 0 | 0s | 0s | add | Class::Date::Rel::
0 | 0 | 0 | 0s | 0s | compare | Class::Date::Rel::
0 | 0 | 0 | 0s | 0s | day | Class::Date::Rel::
0 | 0 | 0 | 0s | 0s | hour | Class::Date::Rel::
0 | 0 | 0 | 0s | 0s | min | Class::Date::Rel::
0 | 0 | 0 | 0s | 0s | mon | Class::Date::Rel::
0 | 0 | 0 | 0s | 0s | mon_part | Class::Date::Rel::
0 | 0 | 0 | 0s | 0s | neg | Class::Date::Rel::
0 | 0 | 0 | 0s | 0s | new | Class::Date::Rel::
0 | 0 | 0 | 0s | 0s | new_copy | Class::Date::Rel::
0 | 0 | 0 | 0s | 0s | new_from_array | Class::Date::Rel::
0 | 0 | 0 | 0s | 0s | new_from_hash | Class::Date::Rel::
0 | 0 | 0 | 0s | 0s | new_from_scalar | Class::Date::Rel::
0 | 0 | 0 | 0s | 0s | new_from_scalar_internal | Class::Date::Rel::
0 | 0 | 0 | 0s | 0s | sec | Class::Date::Rel::
0 | 0 | 0 | 0s | 0s | sec_part | Class::Date::Rel::
0 | 0 | 0 | 0s | 0s | year | Class::Date::Rel::
0 | 0 | 0 | 0s | 0s | __ANON__[:255] | Class::Date::
0 | 0 | 0 | 0s | 0s | __ANON__[:264] | Class::Date::
0 | 0 | 0 | 0s | 0s | __ANON__[:282] | Class::Date::
0 | 0 | 0 | 0s | 0s | __ANON__[:313] | Class::Date::
0 | 0 | 0 | 0s | 0s | __ANON__[:314] | Class::Date::
0 | 0 | 0 | 0s | 0s | __ANON__[:315] | Class::Date::
0 | 0 | 0 | 0s | 0s | __ANON__[:316] | Class::Date::
0 | 0 | 0 | 0s | 0s | __ANON__[:317] | Class::Date::
0 | 0 | 0 | 0s | 0s | __ANON__[:318] | Class::Date::
0 | 0 | 0 | 0s | 0s | __ANON__[:319] | Class::Date::
0 | 0 | 0 | 0s | 0s | __ANON__[:320] | Class::Date::
0 | 0 | 0 | 0s | 0s | __ANON__[:321] | Class::Date::
0 | 0 | 0 | 0s | 0s | __ANON__[:461] | Class::Date::
0 | 0 | 0 | 0s | 0s | __ANON__[:466] | Class::Date::
0 | 0 | 0 | 0s | 0s | __ANON__[:496] | Class::Date::
0 | 0 | 0 | 0s | 0s | _array_from_hash | Class::Date::
0 | 0 | 0 | 0s | 0s | _mon | Class::Date::
0 | 0 | 0 | 0s | 0s | _set_invalid | Class::Date::
0 | 0 | 0 | 0s | 0s | _wday | Class::Date::
0 | 0 | 0 | 0s | 0s | _year | Class::Date::
0 | 0 | 0 | 0s | 0s | add | Class::Date::
0 | 0 | 0 | 0s | 0s | ampm | Class::Date::
0 | 0 | 0 | 0s | 0s | aref | Class::Date::
0 | 0 | 0 | 0s | 0s | array | Class::Date::
0 | 0 | 0 | 0s | 0s | clone | Class::Date::
0 | 0 | 0 | 0s | 0s | compare | Class::Date::
0 | 0 | 0 | 0s | 0s | day | Class::Date::
0 | 0 | 0 | 0s | 0s | days_in_month | Class::Date::
0 | 0 | 0 | 0s | 0s | dmy | Class::Date::
0 | 0 | 0 | 0s | 0s | epoch | Class::Date::
0 | 0 | 0 | 0s | 0s | errmsg | Class::Date::
0 | 0 | 0 | 0s | 0s | error | Class::Date::
0 | 0 | 0 | 0s | 0s | get_epochs | Class::Date::
0 | 0 | 0 | 0s | 0s | gmdate | Class::Date::
0 | 0 | 0 | 0s | 0s | hash | Class::Date::
0 | 0 | 0 | 0s | 0s | hms | Class::Date::
0 | 0 | 0 | 0s | 0s | hour | Class::Date::
0 | 0 | 0 | 0s | 0s | href | Class::Date::
0 | 0 | 0 | 0s | 0s | import | Class::Date::
0 | 0 | 0 | 0s | 0s | is_leap_year | Class::Date::
0 | 0 | 0 | 0s | 0s | isdst | Class::Date::
0 | 0 | 0 | 0s | 0s | localdate | Class::Date::
0 | 0 | 0 | 0s | 0s | mdy | Class::Date::
0 | 0 | 0 | 0s | 0s | meridiam | Class::Date::
0 | 0 | 0 | 0s | 0s | min | Class::Date::
0 | 0 | 0 | 0s | 0s | mon | Class::Date::
0 | 0 | 0 | 0s | 0s | monname | Class::Date::
0 | 0 | 0 | 0s | 0s | month_begin | Class::Date::
0 | 0 | 0 | 0s | 0s | month_end | Class::Date::
0 | 0 | 0 | 0s | 0s | new_copy | Class::Date::
0 | 0 | 0 | 0s | 0s | new_from_hash | Class::Date::
0 | 0 | 0 | 0s | 0s | new_from_scalar_date_parse | Class::Date::
0 | 0 | 0 | 0s | 0s | new_invalid | Class::Date::
0 | 0 | 0 | 0s | 0s | now | Class::Date::
0 | 0 | 0 | 0s | 0s | sec | Class::Date::
0 | 0 | 0 | 0s | 0s | sref | Class::Date::
0 | 0 | 0 | 0s | 0s | strftime | Class::Date::
0 | 0 | 0 | 0s | 0s | string | Class::Date::
0 | 0 | 0 | 0s | 0s | struct | Class::Date::
0 | 0 | 0 | 0s | 0s | subtract | Class::Date::
0 | 0 | 0 | 0s | 0s | to_tz | Class::Date::
0 | 0 | 0 | 0s | 0s | trunc | Class::Date::
0 | 0 | 0 | 0s | 0s | tz | Class::Date::
0 | 0 | 0 | 0s | 0s | tzdst | Class::Date::
0 | 0 | 0 | 0s | 0s | tzoffset | Class::Date::
0 | 0 | 0 | 0s | 0s | wday | Class::Date::
0 | 0 | 0 | 0s | 0s | wdayname | Class::Date::
0 | 0 | 0 | 0s | 0s | yday | Class::Date::
0 | 0 | 0 | 0s | 0s | year | Class::Date::
0 | 0 | 0 | 0s | 0s | ymd | Class::Date::
0 | 0 | 0 | 0s | 0s | yr | Class::Date::
Line | State ments |
Time on line |
Calls | Time in subs |
Code |
---|---|---|---|---|---|
1 | package Class::Date; | ||||
2 | # $Id: Date.pm 126 2005-11-21 21:16:16Z dlux $ | ||||
3 | |||||
4 | 1 | 5µs | require 5.005_03; | ||
5 | |||||
6 | 3 | 124µs | 1 | 28µs | use strict; # spent 28µs making 1 call to strict::import |
7 | use vars qw( # spent 1.27ms making 1 call to vars::import | ||||
8 | $VERSION @EXPORT_OK %EXPORT_TAGS @ISA | ||||
9 | $DATE_FORMAT $DST_ADJUST $MONTH_BORDER_ADJUST $RANGE_CHECK | ||||
10 | @NEW_FROM_SCALAR @ERROR_MESSAGES $WARNINGS | ||||
11 | $DEFAULT_TIMEZONE $LOCAL_TIMEZONE $GMT_TIMEZONE | ||||
12 | $NOTZ_TIMEZONE $RESTORE_TZ | ||||
13 | 3 | 96µs | ); | ||
14 | 3 | 98µs | 1 | 228µs | use Carp; # spent 228µs making 1 call to Exporter::import |
15 | 3 | 89µs | 1 | 266µs | use UNIVERSAL qw(isa); # spent 266µs making 1 call to Exporter::import |
16 | |||||
17 | 3 | 85µs | 1 | 128µs | use Exporter; # spent 128µs making 1 call to Exporter::import |
18 | 3 | 89µs | 1 | 125µs | use DynaLoader; # spent 125µs making 1 call to Exporter::import |
19 | 3 | 22.3ms | 1 | 237µs | use Time::Local; # spent 237µs making 1 call to Exporter::import |
20 | 3 | 882µs | 1 | 1.36ms | use Class::Date::Const; # spent 1.36ms making 1 call to Exporter::import |
21 | |||||
22 | BEGIN { | ||||
23 | 8 | 73µs | $WARNINGS = 1 if !defined $WARNINGS; | ||
24 | 2 | 13µs | if ($] > 5.006) { | ||
25 | *timelocal = *Time::Local::timelocal_nocheck; | ||||
26 | *timegm = *Time::Local::timegm_nocheck; | ||||
27 | } else { | ||||
28 | *timelocal = *Time::Local::timelocal; | ||||
29 | *timegm = *Time::Local::timegm; | ||||
30 | } | ||||
31 | |||||
32 | @ISA=qw(DynaLoader Exporter); | ||||
33 | %EXPORT_TAGS = ( errors => $Class::Date::Const::EXPORT_TAGS{errors}); | ||||
34 | @EXPORT_OK = (qw( date localdate gmdate now @ERROR_MESSAGES), | ||||
35 | @{$EXPORT_TAGS{errors}}); | ||||
36 | |||||
37 | $VERSION = '1.1.9'; | ||||
38 | 1 | 31µs | 1 | 27.7ms | eval { Class::Date->bootstrap($VERSION); }; # spent 27.7ms making 1 call to DynaLoader::bootstrap |
39 | if ($@) { | ||||
40 | warn "Cannot find the XS part of Class::Date, \n". | ||||
41 | " using strftime, tzset and tzname from POSIX module.\n" | ||||
42 | if $WARNINGS; | ||||
43 | require POSIX; | ||||
44 | *strftime_xs = *POSIX::strftime; | ||||
45 | *tzset_xs = *POSIX::tzset; | ||||
46 | *tzname_xs = *POSIX::tzname; | ||||
47 | } | ||||
48 | 1 | 618µs | } | ||
49 | |||||
50 | 1 | 6µs | $GMT_TIMEZONE = 'GMT'; | ||
51 | 1 | 4µs | $DST_ADJUST = 1; | ||
52 | 1 | 4µs | $MONTH_BORDER_ADJUST = 0; | ||
53 | 1 | 26µs | $RANGE_CHECK = 0; | ||
54 | 1 | 4µs | $RESTORE_TZ = 1; | ||
55 | 1 | 5µs | $DATE_FORMAT="%Y-%m-%d %H:%M:%S"; | ||
56 | |||||
57 | 30 | 466µs | # spent 545µs (419+126) within Class::Date::_set_tz which was called 6 times, avg 91µs/call:
# 2 times (161µs+55µs) by Class::Date::_set_temp_tz at line 73, avg 108µs/call
# 2 times (126µs+39µs) by Class::Date::_set_temp_tz at line 75, avg 82µs/call
# once (72µs+16µs) by Class::DBI::_require_class at line 83
# once (60µs+16µs) by Class::DBI::_require_class at line 85 | ||
58 | my $lasttz = $ENV{TZ}; | ||||
59 | 12 | 103µs | if (!defined $tz || $tz eq $NOTZ_TIMEZONE) { | ||
60 | # warn "_set_tz: deleting TZ\n"; | ||||
61 | delete $ENV{TZ}; | ||||
62 | Env::C::unsetenv('TZ') if exists $INC{"Env/C.pm"}; | ||||
63 | } else { | ||||
64 | # warn "_set_tz: setting TZ to $tz\n"; | ||||
65 | $ENV{TZ} = $tz; | ||||
66 | Env::C::setenv('TZ', $tz) if exists $INC{"Env/C.pm"}; | ||||
67 | } | ||||
68 | tzset_xs(); # spent 126µs making 6 calls to Class::Date::tzset_xs, avg 21µs/call | ||||
69 | return $lasttz; | ||||
70 | } | ||||
71 | |||||
72 | 12 | 134µs | sub _set_temp_tz { my ($tz, $sub) = @_; | ||
73 | my $lasttz = _set_tz($tz); # spent 216µs making 2 calls to Class::Date::_set_tz, avg 108µs/call | ||||
74 | 2 | 34µs | 2 | 736µs | my $retval = eval { $sub->(); }; # spent 711µs making 1 call to Class::Date::__ANON__[Class/Date.pm:290]
# spent 25µs making 1 call to Class::Date::__ANON__[Class/Date.pm:308] |
75 | _set_tz($lasttz) if $RESTORE_TZ; # spent 165µs making 2 calls to Class::Date::_set_tz, avg 82µs/call | ||||
76 | die $@ if $@; | ||||
77 | return $retval; | ||||
78 | } | ||||
79 | |||||
80 | 1 | 84µs | 1 | 47µs | tzset_xs(); # spent 47µs making 1 call to Class::Date::tzset_xs |
81 | 1 | 23µs | 1 | 42µs | $LOCAL_TIMEZONE = $DEFAULT_TIMEZONE = local_timezone(); # spent 42µs making 1 call to Class::Date::local_timezone |
82 | { | ||||
83 | 4 | 57µs | 1 | 88µs | my $last_tz = _set_tz(undef); # spent 88µs making 1 call to Class::Date::_set_tz |
84 | $NOTZ_TIMEZONE = local_timezone(); # spent 26µs making 1 call to Class::Date::local_timezone | ||||
85 | _set_tz($last_tz); # spent 76µs making 1 call to Class::Date::_set_tz | ||||
86 | } | ||||
87 | # warn "LOCAL: $LOCAL_TIMEZONE, NOTZ: $NOTZ_TIMEZONE\n"; | ||||
88 | |||||
89 | # this method is used to determine what is the package name of the relative | ||||
90 | # time class. It is used at the operators. You only need to redefine it if | ||||
91 | # you want to derive both Class::Date and Class::Date::Rel. | ||||
92 | # Look at the Class::Date::Rel::ClassDate also. | ||||
93 | 3 | 364µs | 1 | 205µs | use constant ClassDateRel => "Class::Date::Rel"; # spent 205µs making 1 call to constant::import |
94 | 3 | 113µs | 1 | 173µs | use constant ClassDateInvalid => "Class::Date::Invalid"; # spent 173µs making 1 call to constant::import |
95 | |||||
96 | use overload | ||||
97 | '""' => "string", # spent 476µs making 1 call to overload::import | ||||
98 | '-' => "subtract", | ||||
99 | '+' => "add", | ||||
100 | '<=>' => "compare", | ||||
101 | 'cmp' => "compare", | ||||
102 | 3 | 7.94ms | fallback => 1; | ||
103 | |||||
104 | 2 | 176µs | # spent 2.29ms (40µs+2.25) within Class::Date::date which was called
# once (40µs+2.25ms) by K2::DB2::__ANON__[/project/perllib/K2/DB2.pm:49] at line 48 of K2/DB2.pm | ||
105 | return __PACKAGE__ -> new($date,$tz); # spent 2.25ms making 1 call to Class::Date::new | ||||
106 | } | ||||
107 | |||||
108 | sub now () { date(time); } | ||||
109 | |||||
110 | sub localdate ($) { date($_[0] || time, $LOCAL_TIMEZONE) } | ||||
111 | |||||
112 | sub gmdate ($) { date($_[0] || time, $GMT_TIMEZONE) } | ||||
113 | |||||
114 | sub import { | ||||
115 | my $package=shift; | ||||
116 | my @exported; | ||||
117 | foreach my $symbol (@_) { | ||||
118 | if ($symbol eq '-DateParse') { | ||||
119 | if (!$Class::Date::DateParse++) { | ||||
120 | if ( eval { require Date::Parse } ) { | ||||
121 | push @NEW_FROM_SCALAR,\&new_from_scalar_date_parse; | ||||
122 | } else { | ||||
123 | warn "Date::Parse is not available, although it is requested by Class::Date\n" | ||||
124 | if $WARNINGS; | ||||
125 | } | ||||
126 | } | ||||
127 | } elsif ($symbol eq '-EnvC') { | ||||
128 | if (!$Class::Date::EnvC++) { | ||||
129 | if ( !eval { require Env::C } ) { | ||||
130 | warn "Env::C is not available, although it is requested by Class::Date\n" | ||||
131 | if $WARNINGS; | ||||
132 | } | ||||
133 | } | ||||
134 | } else { | ||||
135 | push @exported,$symbol; | ||||
136 | } | ||||
137 | }; | ||||
138 | $package->export_to_level(1,$package,@exported); | ||||
139 | } | ||||
140 | |||||
141 | 6 | 86µs | # spent 2.25ms (95µs+2.15) within Class::Date::new which was called
# once (95µs+2.15ms) by Class::Date::date at line 105 | ||
142 | my $class = ref($proto) || $proto; | ||||
143 | |||||
144 | # if the prototype is an object, not a class, then the timezone will be | ||||
145 | # the same | ||||
146 | $tz = $proto->[c_tz] # spent 6µs making 1 call to UNIVERSAL::isa | ||||
147 | if defined($time) && !defined $tz && isa(ref($proto), __PACKAGE__ ); | ||||
148 | |||||
149 | # Default timezone is used if the timezone cannot be determined otherwise | ||||
150 | $tz = $DEFAULT_TIMEZONE if !defined $tz; | ||||
151 | |||||
152 | return $proto->new_invalid(E_UNDEFINED,"") if !defined $time; | ||||
153 | 1 | 29µs | 2 | 17µs | if (isa($time, __PACKAGE__ )) { # spent 17µs making 2 calls to UNIVERSAL::isa, avg 8µs/call |
154 | return $class->new_copy($time,$tz); | ||||
155 | } elsif (isa($time,'Class::Date::Rel')) { | ||||
156 | return $class->new_from_scalar($time,$tz); | ||||
157 | } elsif (ref($time) eq 'ARRAY') { | ||||
158 | return $class->new_from_array($time,$tz); | ||||
159 | } elsif (ref($time) eq 'SCALAR') { | ||||
160 | return $class->new_from_scalar($$time,$tz); | ||||
161 | } elsif (ref($time) eq 'HASH') { | ||||
162 | return $class->new_from_hash($time,$tz); | ||||
163 | } else { | ||||
164 | return $class->new_from_scalar($time,$tz); # spent 2.13ms making 1 call to Class::Date::new_from_scalar | ||||
165 | } | ||||
166 | } | ||||
167 | |||||
168 | sub new_copy { my ($s,$input,$tz)=@_; | ||||
169 | my $new_object=[ @$input ]; | ||||
170 | # we don't mind $isgmt! | ||||
171 | return bless($new_object, ref($s) || $s); | ||||
172 | } | ||||
173 | |||||
174 | 7 | 245µs | # spent 1.93ms (247µs+1.68) within Class::Date::new_from_array which was called
# once (247µs+1.68ms) by Class::Date::new_from_scalar_internal at line 234 | ||
175 | my ($y,$m,$d,$hh,$mm,$ss,$dst) = @$time; | ||||
176 | my $obj= [ | ||||
177 | ($y||2000)-1900, ($m||1)-1, $d||1, | ||||
178 | $hh||0 , $mm||0 , $ss||0 | ||||
179 | ]; | ||||
180 | $obj->[c_tz]=$tz; | ||||
181 | bless $obj, ref($s) || $s; | ||||
182 | $obj->_recalc_from_struct; # spent 1.68ms making 1 call to Class::Date::_recalc_from_struct | ||||
183 | return $obj; | ||||
184 | } | ||||
185 | |||||
186 | sub new_from_hash { my ($s,$time,$tz) = @_; | ||||
187 | $s->new_from_array(_array_from_hash($time),$tz); | ||||
188 | } | ||||
189 | |||||
190 | sub _array_from_hash { my ($val)=@_; | ||||
191 | [ | ||||
192 | $val->{year} || ($val->{_year} ? $val->{_year} + 1900 : 0 ), | ||||
193 | $val->{mon} || $val->{month} || ( $val->{_mon} ? $val->{_mon} + 1 : 0 ), | ||||
194 | $val->{day} || $val->{mday} || $val->{day_of_month}, | ||||
195 | $val->{hour}, | ||||
196 | exists $val->{min} ? $val->{min} : $val->{minute}, | ||||
197 | exists $val->{sec} ? $val->{sec} : $val->{second}, | ||||
198 | ]; | ||||
199 | } | ||||
200 | |||||
201 | 3 | 18µs | # spent 2.13ms (54µs+2.07) within Class::Date::new_from_scalar which was called
# once (54µs+2.07ms) by Class::Date::new at line 164 | ||
202 | 2 | 39µs | for (my $i=0;$i<@NEW_FROM_SCALAR;$i++) { | ||
203 | my $ret=$NEW_FROM_SCALAR[$i]->($s,$time,$tz); # spent 2.07ms making 1 call to Class::Date::new_from_scalar_internal | ||||
204 | return $ret if defined $ret; | ||||
205 | } | ||||
206 | return $s->new_invalid(E_UNPARSABLE,$time); | ||||
207 | } | ||||
208 | |||||
209 | 3 | 90µs | # spent 2.07ms (99µs+1.97) within Class::Date::new_from_scalar_internal which was called
# once (99µs+1.97ms) by Class::Date::new_from_scalar at line 203 | ||
210 | return undef if !$time; | ||||
211 | |||||
212 | 2 | 53µs | 3 | 43µs | if ($time eq 'now') { # spent 43µs making 3 calls to Class::Date::CORE:match, avg 14µs/call |
213 | # now string | ||||
214 | my $obj=bless [], ref($s) || $s; | ||||
215 | $obj->[c_epoch]=time; | ||||
216 | $obj->[c_tz]=$tz; | ||||
217 | $obj->_recalc_from_epoch; | ||||
218 | return $obj; | ||||
219 | } elsif ($time =~ /^\s*(\d{4})(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)\d*\s*$/) { | ||||
220 | # mysql timestamp | ||||
221 | my ($y,$m,$d,$hh,$mm,$ss)=($1,$2,$3,$4,$5,$6); | ||||
222 | return $s->new_from_array([$y,$m,$d,$hh,$mm,$ss],$tz); | ||||
223 | } elsif ($time =~ /^\s*( \-? \d+ (\.\d+ )? )\s*$/x) { | ||||
224 | # epoch secs | ||||
225 | my $obj=bless [], ref($s) || $s; | ||||
226 | $obj->[c_epoch]=$1; | ||||
227 | $obj->[c_tz]=$tz; | ||||
228 | $obj->_recalc_from_epoch; | ||||
229 | return $obj; | ||||
230 | } elsif ($time =~ m{ ^\s* ( \d{0,4} ) - ( \d\d? ) - ( \d\d? ) | ||||
231 | ( \s+ ( \d\d? ) : ( \d\d? ) ( : ( \d\d? ) (\.\d+)?)? )? }x) { | ||||
232 | my ($y,$m,$d,$hh,$mm,$ss)=($1,$2,$3,$5,$6,$8); | ||||
233 | # ISO(-like) date | ||||
234 | return $s->new_from_array([$y,$m,$d,$hh,$mm,$ss],$tz); # spent 1.93ms making 1 call to Class::Date::new_from_array | ||||
235 | } else { | ||||
236 | return undef; | ||||
237 | } | ||||
238 | } | ||||
239 | |||||
240 | 1 | 8µs | push @NEW_FROM_SCALAR,\&new_from_scalar_internal; | ||
241 | |||||
242 | sub new_from_scalar_date_parse { my ($s,$date,$tz)=@_; | ||||
243 | my $lt; | ||||
244 | my ($ss, $mm, $hh, $day, $month, $year, $zone) = | ||||
245 | Date::Parse::strptime($date); | ||||
246 | $zone = $tz if !defined $zone; | ||||
247 | if ($zone eq $GMT_TIMEZONE) { | ||||
248 | _set_temp_tz($zone, sub { | ||||
249 | $ss = ($lt ||= [ gmtime ])->[0] if !defined $ss; | ||||
250 | $mm = ($lt ||= [ gmtime ])->[1] if !defined $mm; | ||||
251 | $hh = ($lt ||= [ gmtime ])->[2] if !defined $hh; | ||||
252 | $day = ($lt ||= [ gmtime ])->[3] if !defined $day; | ||||
253 | $month = ($lt ||= [ gmtime ])->[4] if !defined $month; | ||||
254 | $year = ($lt ||= [ gmtime ])->[5] if !defined $year; | ||||
255 | }); | ||||
256 | } else { | ||||
257 | _set_temp_tz($zone, sub { | ||||
258 | $ss = ($lt ||= [ localtime ])->[0] if !defined $ss; | ||||
259 | $mm = ($lt ||= [ localtime ])->[1] if !defined $mm; | ||||
260 | $hh = ($lt ||= [ localtime ])->[2] if !defined $hh; | ||||
261 | $day = ($lt ||= [ localtime ])->[3] if !defined $day; | ||||
262 | $month = ($lt ||= [ localtime ])->[4] if !defined $month; | ||||
263 | $year = ($lt ||= [ localtime ])->[5] if !defined $year; | ||||
264 | }); | ||||
265 | } | ||||
266 | return $s->new_from_array( [$year+1900, $month+1, $day, | ||||
267 | $hh, $mm, $ss], $zone); | ||||
268 | } | ||||
269 | |||||
270 | 10 | 89µs | sub _check_sum { my ($s) = @_; | ||
271 | my $sum=0; $sum += $_ || 0 foreach @{$s}[c_year .. c_sec]; | ||||
272 | 1 | 55µs | return $sum; | ||
273 | } | ||||
274 | |||||
275 | # spent 1.68ms (205µs+1.48) within Class::Date::_recalc_from_struct which was called
# once (205µs+1.48ms) by Class::Date::new_from_array at line 182 | ||||
276 | 12 | 129µs | my $s = shift; | ||
277 | $s->[c_isdst] = -1; | ||||
278 | $s->[c_wday] = 0; | ||||
279 | $s->[c_yday] = 0; | ||||
280 | $s->[c_epoch] = 0; # these are required to suppress warinngs; | ||||
281 | 3 | 67µs | eval { | ||
282 | local $SIG{__WARN__} = sub { }; | ||||
283 | my $timecalc = $s->[c_tz] eq $GMT_TIMEZONE ? | ||||
284 | \&timegm : \&timelocal; | ||||
285 | _set_temp_tz($s->[c_tz], | ||||
286 | # spent 711µs (32+679) within Class::Date::__ANON__[/project/perl/lib/Class/Date.pm:290] which was called
# once (32µs+679µs) by Class::Date::_set_temp_tz at line 74 | ||||
287 | $s->[c_epoch] = $timecalc->( | ||||
288 | 1 | 32µs | 1 | 679µs | @{$s}[c_sec,c_min,c_hour,c_day,c_mon], # spent 679µs making 1 call to Time::Local::timelocal_nocheck |
289 | $s->[c_year] + 1900); | ||||
290 | } | ||||
291 | ); # spent 1.04ms making 1 call to Class::Date::_set_temp_tz | ||||
292 | }; | ||||
293 | return $s->_set_invalid(E_INVALID,$@) if $@; | ||||
294 | my $sum = $s->_check_sum; # spent 69µs making 1 call to Class::Date::_check_sum | ||||
295 | $s->_recalc_from_epoch; # spent 303µs making 1 call to Class::Date::_recalc_from_epoch | ||||
296 | @$s[c_error,c_errmsg] = (($s->_check_sum != $sum ? E_RANGE : 0), ""); # spent 68µs making 1 call to Class::Date::_check_sum | ||||
297 | return $s->_set_invalid(E_RANGE,"") if $RANGE_CHECK && $s->[c_error]; | ||||
298 | return 1; | ||||
299 | } | ||||
300 | |||||
301 | 2 | 39µs | # spent 303µs (38+265) within Class::Date::_recalc_from_epoch which was called
# once (38µs+265µs) by Class::Date::_recalc_from_struct at line 295 | ||
302 | _set_temp_tz($s->[c_tz], | ||||
303 | # spent 25µs within Class::Date::__ANON__[/project/perl/lib/Class/Date.pm:308] which was called
# once (25µs+0s) by Class::Date::_set_temp_tz at line 74 | ||||
304 | 1 | 31µs | @{$s}[c_year..c_isdst] = | ||
305 | ($s->[c_tz] eq $GMT_TIMEZONE ? | ||||
306 | gmtime($s->[c_epoch]) : localtime($s->[c_epoch])) | ||||
307 | [5,4,3,2,1,0,6,7,8]; | ||||
308 | } | ||||
309 | ) | ||||
310 | } # spent 265µs making 1 call to Class::Date::_set_temp_tz | ||||
311 | |||||
312 | my $SETHASH = { | ||||
313 | year => sub { shift->[c_year] = shift() - 1900 }, | ||||
314 | _year => sub { shift->[c_year] = shift }, | ||||
315 | month => sub { shift->[c_mon] = shift() - 1 }, | ||||
316 | _month => sub { shift->[c_mon] = shift }, | ||||
317 | day => sub { shift->[c_day] = shift }, | ||||
318 | hour => sub { shift->[c_hour] = shift }, | ||||
319 | min => sub { shift->[c_min] = shift }, | ||||
320 | sec => sub { shift->[c_sec] = shift }, | ||||
321 | tz => sub { shift->[c_tz] = shift }, | ||||
322 | 1 | 19µs | }; | ||
323 | 1 | 8µs | $SETHASH->{mon} = $SETHASH->{month}; | ||
324 | 1 | 5µs | $SETHASH->{_mon} = $SETHASH->{_month}; | ||
325 | 1 | 6µs | $SETHASH->{mday} = $SETHASH->{day_of_month} = $SETHASH->{day}; | ||
326 | 1 | 5µs | $SETHASH->{minute} = $SETHASH->{min}; | ||
327 | 1 | 4µs | $SETHASH->{second} = $SETHASH->{sec}; | ||
328 | |||||
329 | sub clone { | ||||
330 | my $s = shift; | ||||
331 | my $new_date = $s->new_copy($s); | ||||
332 | while (@_) { | ||||
333 | my $key = shift; | ||||
334 | my $value = shift; | ||||
335 | $SETHASH->{$key}->($value,$new_date); | ||||
336 | }; | ||||
337 | $new_date->_recalc_from_struct; | ||||
338 | return $new_date; | ||||
339 | } | ||||
340 | |||||
341 | 1 | 8µs | *set = *clone; # compatibility | ||
342 | |||||
343 | sub year { shift->[c_year] +1900 } | ||||
344 | sub _year { shift->[c_year] } | ||||
345 | sub yr { shift->[c_year] % 100 } | ||||
346 | sub mon { shift->[c_mon] +1 } | ||||
347 | 1 | 4µs | *month = *mon; | ||
348 | sub _mon { shift->[c_mon] } | ||||
349 | 1 | 4µs | *_month = *_mon; | ||
350 | sub day { shift->[c_day] } | ||||
351 | 1 | 7µs | *day_of_month= *mday = *day; | ||
352 | sub hour { shift->[c_hour] } | ||||
353 | sub min { shift->[c_min] } | ||||
354 | 1 | 5µs | *minute = *min; | ||
355 | sub sec { shift->[c_sec] } | ||||
356 | 1 | 5µs | *second = *sec; | ||
357 | sub wday { shift->[c_wday] + 1 } | ||||
358 | sub _wday { shift->[c_wday] } | ||||
359 | 1 | 5µs | *day_of_week = *_wday; | ||
360 | sub yday { shift->[c_yday] } | ||||
361 | 1 | 5µs | *day_of_year = *yday; | ||
362 | sub isdst { shift->[c_isdst] } | ||||
363 | 1 | 6µs | *daylight_savings = \&isdst; | ||
364 | sub epoch { shift->[c_epoch] } | ||||
365 | 1 | 4µs | *as_sec = *epoch; # for compatibility | ||
366 | sub tz { shift->[c_tz] } | ||||
367 | sub tzdst { shift->strftime("%Z") } | ||||
368 | |||||
369 | sub monname { shift->strftime('%B') } | ||||
370 | 1 | 5µs | *monthname = *monname; | ||
371 | sub wdayname { shift->strftime('%A') } | ||||
372 | 1 | 5µs | *day_of_weekname= *wdayname; | ||
373 | |||||
374 | sub error { shift->[c_error] } | ||||
375 | sub errmsg { my ($s) = @_; | ||||
376 | sprintf $ERROR_MESSAGES[ $s->[c_error] ]."\n", $s->[c_errmsg] | ||||
377 | } | ||||
378 | 1 | 6µs | *errstr = *errmsg; | ||
379 | |||||
380 | sub new_invalid { my ($proto,$error,$errmsg) = @_; | ||||
381 | bless([],ref($proto) || $proto)->_set_invalid($error,$errmsg); | ||||
382 | } | ||||
383 | |||||
384 | sub _set_invalid { my ($s,$error,$errmsg) = @_; | ||||
385 | bless($s,$s->ClassDateInvalid); | ||||
386 | @$s = (); | ||||
387 | @$s[ci_error, ci_errmsg] = ($error,$errmsg); | ||||
388 | return $s; | ||||
389 | } | ||||
390 | |||||
391 | sub ampm { my ($s) = @_; | ||||
392 | return $s->[c_hour] < 12 ? "AM" : "PM"; | ||||
393 | } | ||||
394 | |||||
395 | sub meridiam { my ($s) = @_; | ||||
396 | my $hour = $s->[c_hour] % 12; | ||||
397 | if( $hour == 0 ) { $hour = 12; } | ||||
398 | sprintf('%02d:%02d %s', $hour, $s->[c_min], $s->ampm); | ||||
399 | } | ||||
400 | |||||
401 | sub hms { sprintf('%02d:%02d:%02d', @{ shift() }[c_hour,c_min,c_sec]) } | ||||
402 | |||||
403 | sub ymd { my ($s)=@_; | ||||
404 | sprintf('%04d/%02d/%02d', $s->year, $s->mon, $s->[c_day]) | ||||
405 | } | ||||
406 | |||||
407 | sub mdy { my ($s)=@_; | ||||
408 | sprintf('%02d/%02d/%04d', $s->mon, $s->[c_day], $s->year) | ||||
409 | } | ||||
410 | |||||
411 | sub dmy { my ($s)=@_; | ||||
412 | sprintf('%02d/%02d/%04d', $s->[c_day], $s->mon, $s->year) | ||||
413 | } | ||||
414 | |||||
415 | sub array { my ($s)=@_; | ||||
416 | my @return=@{$s}[c_year .. c_sec]; | ||||
417 | $return[c_year]+=1900; | ||||
418 | $return[c_mon]+=1; | ||||
419 | @return; | ||||
420 | } | ||||
421 | |||||
422 | sub aref { return [ shift()->array ] } | ||||
423 | 1 | 5µs | *as_array = *aref; | ||
424 | |||||
425 | sub struct { | ||||
426 | return ( @{ shift() } | ||||
427 | [c_sec,c_min,c_hour,c_day,c_mon,c_year,c_wday,c_yday,c_isdst] ) | ||||
428 | } | ||||
429 | |||||
430 | sub sref { return [ shift()->struct ] } | ||||
431 | |||||
432 | sub href { my ($s)=@_; | ||||
433 | my @struct=$s->struct; | ||||
434 | my $h={}; | ||||
435 | foreach my $key (qw(sec min hour day _month _year wday yday isdst)) { | ||||
436 | $h->{$key}=shift @struct; | ||||
437 | } | ||||
438 | $h->{epoch} = $s->[c_epoch]; | ||||
439 | $h->{year} = 1900 + $h->{_year}; | ||||
440 | $h->{month} = $h->{_month} + 1; | ||||
441 | $h->{minute} = $h->{min}; | ||||
442 | return $h; | ||||
443 | } | ||||
444 | |||||
445 | 1 | 5µs | *as_hash=*href; | ||
446 | |||||
447 | sub hash { return %{ shift->href } } | ||||
448 | |||||
449 | # Thanks to Tony Olekshy <olekshy@cs.ualberta.ca> for this algorithm | ||||
450 | # ripped from Time::Object by Matt Sergeant | ||||
451 | sub tzoffset { my ($s)=@_; | ||||
452 | my $epoch = $s->[c_epoch]; | ||||
453 | my $j = sub { # Tweaked Julian day number algorithm. | ||||
454 | my ($s,$n,$h,$d,$m,$y) = @_; $m += 1; $y += 1900; | ||||
455 | # Standard Julian day number algorithm without constant. | ||||
456 | my $y1 = $m > 2 ? $y : $y - 1; | ||||
457 | my $m1 = $m > 2 ? $m + 1 : $m + 13; | ||||
458 | my $day = int(365.25 * $y1) + int(30.6001 * $m1) + $d; | ||||
459 | # Modify to include hours/mins/secs in floating portion. | ||||
460 | return $day + ($h + ($n + $s / 60) / 60) / 24; | ||||
461 | }; | ||||
462 | # Compute floating offset in hours. | ||||
463 | my $delta = _set_temp_tz($s->[c_tz], | ||||
464 | sub { | ||||
465 | 24 * (&$j(localtime $epoch) - &$j(gmtime $epoch)); | ||||
466 | } | ||||
467 | ); | ||||
468 | # Return value in seconds rounded to nearest minute. | ||||
469 | return int($delta * 60 + ($delta >= 0 ? 0.5 : -0.5)) * 60; | ||||
470 | } | ||||
471 | |||||
472 | sub month_begin { my ($s) = @_; | ||||
473 | my $aref = $s->aref; | ||||
474 | $aref->[2] = 1; | ||||
475 | return $s->new($aref); | ||||
476 | } | ||||
477 | |||||
478 | sub month_end { my ($s)=@_; | ||||
479 | return $s->clone(day => 1)+'1M'-'1D'; | ||||
480 | } | ||||
481 | |||||
482 | sub days_in_month { | ||||
483 | shift->month_end->mday; | ||||
484 | } | ||||
485 | |||||
486 | sub is_leap_year { my ($s) = @_; | ||||
487 | my $new_date; | ||||
488 | eval { | ||||
489 | $new_date = $s->new([$s->year, 2, 29],$s->tz); | ||||
490 | } or return 0; | ||||
491 | return $new_date->day == 29; | ||||
492 | } | ||||
493 | |||||
494 | sub strftime { my ($s,$format)=@_; | ||||
495 | $format ||= "%a, %d %b %Y %H:%M:%S %Z"; | ||||
496 | my $fmt = _set_temp_tz($s->[c_tz], sub { strftime_xs($format,$s->struct) } ); | ||||
497 | return $fmt; | ||||
498 | } | ||||
499 | |||||
500 | sub string { my ($s) = @_; | ||||
501 | $s->strftime($DATE_FORMAT); | ||||
502 | } | ||||
503 | |||||
504 | sub subtract { my ($s,$rhs)=@_; | ||||
505 | if (isa(ref($rhs), __PACKAGE__ )) { | ||||
506 | my $dst_adjust = 0; | ||||
507 | $dst_adjust = 60*60*( $s->[c_isdst]-$rhs->[c_isdst] ) if $DST_ADJUST; | ||||
508 | return $s->ClassDateRel->new($s->[c_epoch]-$rhs->[c_epoch]+$dst_adjust); | ||||
509 | } elsif (isa(ref($rhs), "Class::Date::Rel")) { | ||||
510 | return $s->add(-$rhs); | ||||
511 | } elsif ($rhs) { | ||||
512 | return $s->add($s->ClassDateRel->new($rhs)->neg); | ||||
513 | } else { | ||||
514 | return $s; | ||||
515 | } | ||||
516 | } | ||||
517 | |||||
518 | sub add { my ($s,$rhs)=@_; | ||||
519 | local $RANGE_CHECK; | ||||
520 | $rhs=$s->ClassDateRel->new($rhs) if !isa($rhs,'Class::Date::Rel'); | ||||
521 | |||||
522 | return $s if !isa($rhs,'Class::Date::Rel'); | ||||
523 | |||||
524 | # adding seconds | ||||
525 | my $retval= $rhs->[cs_sec] ? | ||||
526 | $s->new_from_scalar($s->[c_epoch]+$rhs->[cs_sec],$s->[c_tz]) : | ||||
527 | $s->new_copy($s); | ||||
528 | |||||
529 | # adjust DST if necessary | ||||
530 | if ( $DST_ADJUST && (my $dstdiff=$retval->[c_isdst]-$s->[c_isdst])) { | ||||
531 | $retval->[c_epoch] -= $dstdiff*60*60; | ||||
532 | $retval->_recalc_from_epoch; | ||||
533 | } | ||||
534 | |||||
535 | # adding months | ||||
536 | if ($rhs->[cs_mon]) { | ||||
537 | $retval->[c_mon]+=$rhs->[cs_mon]; | ||||
538 | my $year_diff= $retval->[c_mon]>0 ? # instead of POSIX::floor | ||||
539 | int ($retval->[c_mon]/12) : | ||||
540 | int (($retval->[c_mon]-11)/12); | ||||
541 | $retval->[c_mon] -= 12*$year_diff; | ||||
542 | my $expected_month = $retval->[c_mon]; | ||||
543 | $retval->[c_year] += $year_diff; | ||||
544 | $retval->_recalc_from_struct; | ||||
545 | |||||
546 | # adjust month border if necessary | ||||
547 | if ($MONTH_BORDER_ADJUST && $retval && $expected_month != $retval->[c_mon]) { | ||||
548 | $retval->[c_epoch] -= $retval->[c_day]*60*60*24; | ||||
549 | $retval->_recalc_from_epoch; | ||||
550 | } | ||||
551 | } | ||||
552 | |||||
553 | # sigh! We have finished! | ||||
554 | return $retval; | ||||
555 | } | ||||
556 | |||||
557 | sub trunc { my ($s)=@_; | ||||
558 | return $s->new_from_array([$s->year,$s->month,$s->day,0,0,0],$s->[c_tz]); | ||||
559 | } | ||||
560 | |||||
561 | 1 | 5µs | *truncate = *trunc; | ||
562 | |||||
563 | sub get_epochs { | ||||
564 | my ($lhs,$rhs,$reverse)=@_; | ||||
565 | if (!isa(ref($rhs), __PACKAGE__ )) { | ||||
566 | $rhs = $lhs->new($rhs); | ||||
567 | } | ||||
568 | my $repoch= $rhs ? $rhs->epoch : 0; | ||||
569 | return $repoch, $lhs->epoch if $reverse; | ||||
570 | return $lhs->epoch, $repoch; | ||||
571 | } | ||||
572 | |||||
573 | sub compare { | ||||
574 | my ($lhs, $rhs) = get_epochs(@_); | ||||
575 | return $lhs <=> $rhs; | ||||
576 | } | ||||
577 | |||||
578 | sub local_timezone { | ||||
579 | 2 | 76µs | 2 | 16µs | return (tzname_xs())[0]; # spent 16µs making 2 calls to Class::Date::tzname_xs, avg 8µs/call |
580 | } | ||||
581 | |||||
582 | sub to_tz { my ($s, $tz) = @_; | ||||
583 | return $s->new($s->epoch, $tz); | ||||
584 | } | ||||
585 | |||||
586 | package Class::Date::Rel; | ||||
587 | 3 | 93µs | 1 | 27µs | use strict; # spent 27µs making 1 call to strict::import |
588 | 3 | 103µs | 1 | 140µs | use vars qw(@NEW_FROM_SCALAR); # spent 140µs making 1 call to vars::import |
589 | 3 | 81µs | 1 | 181µs | use UNIVERSAL qw(isa); # spent 181µs making 1 call to Exporter::import |
590 | 3 | 105µs | 1 | 1.39ms | use Class::Date::Const; # spent 1.39ms making 1 call to Exporter::import |
591 | |||||
592 | 3 | 95µs | 1 | 181µs | use constant SEC_PER_MONTH => 2_629_744; # spent 181µs making 1 call to constant::import |
593 | |||||
594 | # see the ClassDateRel const in package Class::Date | ||||
595 | 3 | 119µs | 1 | 187µs | use constant ClassDate => "Class::Date"; # spent 187µs making 1 call to constant::import |
596 | |||||
597 | use overload | ||||
598 | '0+' => "sec", # spent 571µs making 1 call to overload::import | ||||
599 | '""' => "sec", | ||||
600 | '<=>' => "compare", | ||||
601 | 'cmp' => "compare", | ||||
602 | '+' => "add", | ||||
603 | 'neg' => "neg", | ||||
604 | 3 | 2.04ms | fallback => 1; | ||
605 | |||||
606 | sub new { my ($proto,$val)=@_; | ||||
607 | my $class = ref($proto) || $proto; | ||||
608 | return undef if !defined $val; | ||||
609 | if (isa(ref($val), __PACKAGE__ )) { | ||||
610 | return $class->new_copy($val); | ||||
611 | } elsif (ref($val) eq 'ARRAY') { | ||||
612 | return $class->new_from_array($val); | ||||
613 | } elsif (ref($val) eq 'HASH') { | ||||
614 | return $class->new_from_hash($val); | ||||
615 | } elsif (ref($val) eq 'SCALAR') { | ||||
616 | return $class->new_from_scalar($$val); | ||||
617 | } else { | ||||
618 | return $class->new_from_scalar($val); | ||||
619 | }; | ||||
620 | } | ||||
621 | |||||
622 | sub new_copy { my ($s,$val)=@_; | ||||
623 | return bless([@$val], ref($s)||$s); | ||||
624 | } | ||||
625 | |||||
626 | sub new_from_array { my ($s,$val) = @_; | ||||
627 | my ($y,$m,$d,$hh,$mm,$ss) = @$val; | ||||
628 | return bless([ ($y || 0) * 12 + $m , ($ss || 0) + | ||||
629 | 60*(($mm || 0) + 60*(($hh || 0) + 24* ($d || 0))) ], ref($s)||$s); | ||||
630 | } | ||||
631 | |||||
632 | sub new_from_hash { my ($s,$val) = @_; | ||||
633 | $s->new_from_array(Class::Date::_array_from_hash($val)); | ||||
634 | } | ||||
635 | |||||
636 | sub new_from_scalar { my ($s,$val)=@_; | ||||
637 | for (my $i=0;$i<@NEW_FROM_SCALAR;$i++) { | ||||
638 | my $ret=$NEW_FROM_SCALAR[$i]->($s,$val); | ||||
639 | return $ret if defined $ret; | ||||
640 | } | ||||
641 | return undef; | ||||
642 | } | ||||
643 | |||||
644 | sub new_from_scalar_internal { my ($s,$val)=@_; | ||||
645 | return undef if !defined $val; | ||||
646 | return bless([0,$1],ref($s) || $s) | ||||
647 | if $val =~ / ^ \s* ( \-? \d+ ( \. \d* )? ) \s* $/x; | ||||
648 | |||||
649 | if ($val =~ m{ ^\s* ( \d{1,4} ) - ( \d\d? ) - ( \d\d? ) | ||||
650 | ( \s+ ( \d\d? ) : ( \d\d? ) ( : ( \d\d? )? (\.\d+)? )? )? }x ) { | ||||
651 | # ISO date | ||||
652 | my ($y,$m,$d,$hh,$mm,$ss)=($1,$2,$3,$5,$6,$8); | ||||
653 | return $s->new_from_array([$y,$m,$d,$hh,$mm,$ss]); | ||||
654 | } | ||||
655 | |||||
656 | my ($y,$m,$d,$hh,$mm,$ss)=(0,0,0,0,0,0); | ||||
657 | $val =~ s{ \G \s* ( \-? \d+) \s* (Y|M|D|h|m|s) }{ | ||||
658 | my ($num,$cmd)=($1,$2); | ||||
659 | if ($cmd eq 'Y') { | ||||
660 | $y=$num; | ||||
661 | } elsif ($cmd eq 'M') { | ||||
662 | $m=$num; | ||||
663 | } elsif ($cmd eq 'D') { | ||||
664 | $d=$num; | ||||
665 | } elsif ($cmd eq 'h') { | ||||
666 | $hh=$num; | ||||
667 | } elsif ($cmd eq 'm') { | ||||
668 | $mm=$num; | ||||
669 | } elsif ($cmd eq 's') { | ||||
670 | $ss=$num; | ||||
671 | } | ||||
672 | ""; | ||||
673 | }gexi; | ||||
674 | return $s->new_from_array([$y,$m,$d,$hh,$mm,$ss]); | ||||
675 | } | ||||
676 | |||||
677 | 1 | 6µs | push @NEW_FROM_SCALAR,\&new_from_scalar_internal; | ||
678 | |||||
679 | sub compare { my ($s,$val2,$reverse) = @_; | ||||
680 | my $rev_multiply=$reverse ? -1 : 1; | ||||
681 | if (isa($val2, __PACKAGE__ )) { | ||||
682 | return ($s->sec <=> $val2->sec) * $rev_multiply; | ||||
683 | } else { | ||||
684 | my $date_obj=$s->new($val2); | ||||
685 | return ($s->sec <=> 0) * $rev_multiply if !defined $date_obj; | ||||
686 | return ($s->sec <=> $date_obj->sec) * $rev_multiply; | ||||
687 | } | ||||
688 | } | ||||
689 | |||||
690 | sub add { my ($s,$val2)=@_; | ||||
691 | if (my $reldate=$s->new($val2)) { | ||||
692 | my $months=$s->[cs_mon] + $reldate->[cs_mon]; | ||||
693 | my $secs =$s->[cs_sec] + $reldate->[cs_sec]; | ||||
694 | return $s->new_from_hash({ month => $months, sec => $secs }) if $months; | ||||
695 | return $secs; | ||||
696 | } else { | ||||
697 | return $s; | ||||
698 | } | ||||
699 | } | ||||
700 | |||||
701 | sub neg { my ($s)=@_; | ||||
702 | return $s->new_from_hash({ | ||||
703 | month => -$s->[cs_mon], | ||||
704 | sec => -$s->[cs_sec] | ||||
705 | }); | ||||
706 | } | ||||
707 | |||||
708 | sub year { shift->sec / (SEC_PER_MONTH*12) } | ||||
709 | sub mon { shift->sec / SEC_PER_MONTH } | ||||
710 | 1 | 5µs | *month = *mon; | ||
711 | sub day { shift->sec / (60*60*24) } | ||||
712 | sub hour { shift->sec / (60*60) } | ||||
713 | sub min { shift->sec / 60 } | ||||
714 | 1 | 5µs | *minute = *min; | ||
715 | sub sec { my ($s)=@_; $s->[cs_sec] + SEC_PER_MONTH * $s->[cs_mon]; } | ||||
716 | 1 | 5µs | *second = *sec; | ||
717 | |||||
718 | sub sec_part { shift->[cs_sec] } | ||||
719 | 1 | 5µs | *second_part = *sec_part; | ||
720 | sub mon_part { shift->[cs_mon] } | ||||
721 | 1 | 5µs | *month_part = *mon_part; | ||
722 | |||||
723 | package Class::Date::Invalid; | ||||
724 | 3 | 84µs | 1 | 25µs | use strict; # spent 25µs making 1 call to strict::import |
725 | 3 | 147µs | 1 | 1.40ms | use Class::Date::Const; # spent 1.40ms making 1 call to Exporter::import |
726 | |||||
727 | use overload | ||||
728 | '0+' => "zero", # spent 551µs making 1 call to overload::import | ||||
729 | '""' => "empty", | ||||
730 | '<=>' => "compare", | ||||
731 | 'cmp' => "compare", | ||||
732 | '+' => "zero", | ||||
733 | '!' => "true", | ||||
734 | 3 | 573µs | fallback => 1; | ||
735 | |||||
736 | sub empty { "" } | ||||
737 | sub zero { 0 } | ||||
738 | sub true { 1 } | ||||
739 | |||||
740 | sub compare { return ($_[1] ? 1 : 0) * ($_[2] ? -1 : 1) } | ||||
741 | |||||
742 | sub error { shift->[ci_error]; } | ||||
743 | |||||
744 | sub errmsg { my ($s) = @_; | ||||
745 | sprintf $ERROR_MESSAGES[ $s->[ci_error] ]."\n", $s->[ci_errmsg] | ||||
746 | } | ||||
747 | 1 | 5µs | *errstr = *errmsg; | ||
748 | |||||
749 | sub AUTOLOAD { undef } | ||||
750 | |||||
751 | 1 | 64µs | 1; | ||
# spent 43µs within Class::Date::CORE:match which was called 3 times, avg 14µs/call:
# 3 times (43µs+0s) by Class::Date::new_from_scalar_internal at line 212 of Class/Date.pm, avg 14µs/call | |||||
# spent 21µs within Class::Date::bootstrap which was called
# once (21µs+0s) by DynaLoader::bootstrap at line 253 of DynaLoader.pm | |||||
# spent 16µs within Class::Date::tzname_xs which was called 2 times, avg 8µs/call:
# 2 times (16µs+0s) by Class::Date::local_timezone at line 579 of Class/Date.pm, avg 8µs/call | |||||
# spent 173µs within Class::Date::tzset_xs which was called 7 times, avg 25µs/call:
# 6 times (126µs+0s) by Class::Date::_set_tz at line 68 of Class/Date.pm, avg 21µs/call
# once (47µs+0s) by Class::DBI::_require_class at line 80 of Class/Date.pm |