| 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 | Class::Date::_set_tz |
| 1 | 1 | 1 | 247µs | 1.93ms | Class::Date::new_from_array |
| 1 | 1 | 1 | 205µs | 1.68ms | Class::Date::_recalc_from_struct |
| 2 | 2 | 1 | 187µs | 1.30ms | Class::Date::_set_temp_tz |
| 7 | 2 | 2 | 173µs | 173µs | Class::Date::tzset_xs (xsub) |
| 2 | 2 | 1 | 137µs | 137µs | Class::Date::_check_sum |
| 1 | 1 | 1 | 99µs | 2.07ms | Class::Date::new_from_scalar_internal |
| 1 | 1 | 1 | 95µs | 2.25ms | Class::Date::new |
| 1 | 1 | 1 | 54µs | 2.13ms | Class::Date::new_from_scalar |
| 2 | 2 | 1 | 52µs | 68µs | Class::Date::local_timezone |
| 3 | 1 | 2 | 43µs | 43µs | Class::Date::CORE:match (opcode) |
| 1 | 1 | 1 | 40µs | 2.29ms | Class::Date::date |
| 1 | 1 | 1 | 38µs | 303µs | Class::Date::_recalc_from_epoch |
| 1 | 1 | 1 | 32µs | 711µs | Class::Date::__ANON__[:290] |
| 1 | 1 | 1 | 25µs | 25µs | Class::Date::__ANON__[:308] |
| 1 | 1 | 2 | 21µs | 21µs | Class::Date::bootstrap (xsub) |
| 2 | 1 | 2 | 16µs | 16µs | Class::Date::tzname_xs (xsub) |
| 0 | 0 | 0 | 0s | 0s | Class::Date::BEGIN |
| 0 | 0 | 0 | 0s | 0s | Class::Date::Invalid::AUTOLOAD |
| 0 | 0 | 0 | 0s | 0s | Class::Date::Invalid::BEGIN |
| 0 | 0 | 0 | 0s | 0s | Class::Date::Invalid::compare |
| 0 | 0 | 0 | 0s | 0s | Class::Date::Invalid::empty |
| 0 | 0 | 0 | 0s | 0s | Class::Date::Invalid::errmsg |
| 0 | 0 | 0 | 0s | 0s | Class::Date::Invalid::error |
| 0 | 0 | 0 | 0s | 0s | Class::Date::Invalid::true |
| 0 | 0 | 0 | 0s | 0s | Class::Date::Invalid::zero |
| 0 | 0 | 0 | 0s | 0s | Class::Date::Rel::BEGIN |
| 0 | 0 | 0 | 0s | 0s | Class::Date::Rel::add |
| 0 | 0 | 0 | 0s | 0s | Class::Date::Rel::compare |
| 0 | 0 | 0 | 0s | 0s | Class::Date::Rel::day |
| 0 | 0 | 0 | 0s | 0s | Class::Date::Rel::hour |
| 0 | 0 | 0 | 0s | 0s | Class::Date::Rel::min |
| 0 | 0 | 0 | 0s | 0s | Class::Date::Rel::mon |
| 0 | 0 | 0 | 0s | 0s | Class::Date::Rel::mon_part |
| 0 | 0 | 0 | 0s | 0s | Class::Date::Rel::neg |
| 0 | 0 | 0 | 0s | 0s | Class::Date::Rel::new |
| 0 | 0 | 0 | 0s | 0s | Class::Date::Rel::new_copy |
| 0 | 0 | 0 | 0s | 0s | Class::Date::Rel::new_from_array |
| 0 | 0 | 0 | 0s | 0s | Class::Date::Rel::new_from_hash |
| 0 | 0 | 0 | 0s | 0s | Class::Date::Rel::new_from_scalar |
| 0 | 0 | 0 | 0s | 0s | Class::Date::Rel::new_from_scalar_internal |
| 0 | 0 | 0 | 0s | 0s | Class::Date::Rel::sec |
| 0 | 0 | 0 | 0s | 0s | Class::Date::Rel::sec_part |
| 0 | 0 | 0 | 0s | 0s | Class::Date::Rel::year |
| 0 | 0 | 0 | 0s | 0s | Class::Date::__ANON__[:255] |
| 0 | 0 | 0 | 0s | 0s | Class::Date::__ANON__[:264] |
| 0 | 0 | 0 | 0s | 0s | Class::Date::__ANON__[:282] |
| 0 | 0 | 0 | 0s | 0s | Class::Date::__ANON__[:313] |
| 0 | 0 | 0 | 0s | 0s | Class::Date::__ANON__[:314] |
| 0 | 0 | 0 | 0s | 0s | Class::Date::__ANON__[:315] |
| 0 | 0 | 0 | 0s | 0s | Class::Date::__ANON__[:316] |
| 0 | 0 | 0 | 0s | 0s | Class::Date::__ANON__[:317] |
| 0 | 0 | 0 | 0s | 0s | Class::Date::__ANON__[:318] |
| 0 | 0 | 0 | 0s | 0s | Class::Date::__ANON__[:319] |
| 0 | 0 | 0 | 0s | 0s | Class::Date::__ANON__[:320] |
| 0 | 0 | 0 | 0s | 0s | Class::Date::__ANON__[:321] |
| 0 | 0 | 0 | 0s | 0s | Class::Date::__ANON__[:461] |
| 0 | 0 | 0 | 0s | 0s | Class::Date::__ANON__[:466] |
| 0 | 0 | 0 | 0s | 0s | Class::Date::__ANON__[:496] |
| 0 | 0 | 0 | 0s | 0s | Class::Date::_array_from_hash |
| 0 | 0 | 0 | 0s | 0s | Class::Date::_mon |
| 0 | 0 | 0 | 0s | 0s | Class::Date::_set_invalid |
| 0 | 0 | 0 | 0s | 0s | Class::Date::_wday |
| 0 | 0 | 0 | 0s | 0s | Class::Date::_year |
| 0 | 0 | 0 | 0s | 0s | Class::Date::add |
| 0 | 0 | 0 | 0s | 0s | Class::Date::ampm |
| 0 | 0 | 0 | 0s | 0s | Class::Date::aref |
| 0 | 0 | 0 | 0s | 0s | Class::Date::array |
| 0 | 0 | 0 | 0s | 0s | Class::Date::clone |
| 0 | 0 | 0 | 0s | 0s | Class::Date::compare |
| 0 | 0 | 0 | 0s | 0s | Class::Date::day |
| 0 | 0 | 0 | 0s | 0s | Class::Date::days_in_month |
| 0 | 0 | 0 | 0s | 0s | Class::Date::dmy |
| 0 | 0 | 0 | 0s | 0s | Class::Date::epoch |
| 0 | 0 | 0 | 0s | 0s | Class::Date::errmsg |
| 0 | 0 | 0 | 0s | 0s | Class::Date::error |
| 0 | 0 | 0 | 0s | 0s | Class::Date::get_epochs |
| 0 | 0 | 0 | 0s | 0s | Class::Date::gmdate |
| 0 | 0 | 0 | 0s | 0s | Class::Date::hash |
| 0 | 0 | 0 | 0s | 0s | Class::Date::hms |
| 0 | 0 | 0 | 0s | 0s | Class::Date::hour |
| 0 | 0 | 0 | 0s | 0s | Class::Date::href |
| 0 | 0 | 0 | 0s | 0s | Class::Date::import |
| 0 | 0 | 0 | 0s | 0s | Class::Date::is_leap_year |
| 0 | 0 | 0 | 0s | 0s | Class::Date::isdst |
| 0 | 0 | 0 | 0s | 0s | Class::Date::localdate |
| 0 | 0 | 0 | 0s | 0s | Class::Date::mdy |
| 0 | 0 | 0 | 0s | 0s | Class::Date::meridiam |
| 0 | 0 | 0 | 0s | 0s | Class::Date::min |
| 0 | 0 | 0 | 0s | 0s | Class::Date::mon |
| 0 | 0 | 0 | 0s | 0s | Class::Date::monname |
| 0 | 0 | 0 | 0s | 0s | Class::Date::month_begin |
| 0 | 0 | 0 | 0s | 0s | Class::Date::month_end |
| 0 | 0 | 0 | 0s | 0s | Class::Date::new_copy |
| 0 | 0 | 0 | 0s | 0s | Class::Date::new_from_hash |
| 0 | 0 | 0 | 0s | 0s | Class::Date::new_from_scalar_date_parse |
| 0 | 0 | 0 | 0s | 0s | Class::Date::new_invalid |
| 0 | 0 | 0 | 0s | 0s | Class::Date::now |
| 0 | 0 | 0 | 0s | 0s | Class::Date::sec |
| 0 | 0 | 0 | 0s | 0s | Class::Date::sref |
| 0 | 0 | 0 | 0s | 0s | Class::Date::strftime |
| 0 | 0 | 0 | 0s | 0s | Class::Date::string |
| 0 | 0 | 0 | 0s | 0s | Class::Date::struct |
| 0 | 0 | 0 | 0s | 0s | Class::Date::subtract |
| 0 | 0 | 0 | 0s | 0s | Class::Date::to_tz |
| 0 | 0 | 0 | 0s | 0s | Class::Date::trunc |
| 0 | 0 | 0 | 0s | 0s | Class::Date::tz |
| 0 | 0 | 0 | 0s | 0s | Class::Date::tzdst |
| 0 | 0 | 0 | 0s | 0s | Class::Date::tzoffset |
| 0 | 0 | 0 | 0s | 0s | Class::Date::wday |
| 0 | 0 | 0 | 0s | 0s | Class::Date::wdayname |
| 0 | 0 | 0 | 0s | 0s | Class::Date::yday |
| 0 | 0 | 0 | 0s | 0s | Class::Date::year |
| 0 | 0 | 0 | 0s | 0s | Class::Date::ymd |
| 0 | 0 | 0 | 0s | 0s | Class::Date::yr |
| 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 |