← Index
NYTProf Performance Profile   « line view »
For t/bug-md-11.t
  Run on Fri Mar 8 13:27:24 2024
Reported on Fri Mar 8 13:30:23 2024

Filename/home/micha/.plenv/versions/5.38.2/lib/perl5/site_perl/5.38.2/Time/Local.pm
StatementsExecuted 37 statements in 810µs
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
1119µs10µsTime::Local::::BEGIN@3Time::Local::BEGIN@3
1118µs10µsTime::Local::::_daygmTime::Local::_daygm
1113µs24µsTime::Local::::BEGIN@34Time::Local::BEGIN@34
1113µs12µsTime::Local::::BEGIN@6Time::Local::BEGIN@6
1113µs12µsTime::Local::::BEGIN@10Time::Local::BEGIN@10
1113µs19µsTime::Local::::BEGIN@35Time::Local::BEGIN@35
1112µs16µsTime::Local::::BEGIN@36Time::Local::BEGIN@36
1112µs2µsTime::Local::::BEGIN@5Time::Local::BEGIN@5
0000s0sTime::Local::::_is_leap_yearTime::Local::_is_leap_year
0000s0sTime::Local::::_timegmTime::Local::_timegm
0000s0sTime::Local::::timegmTime::Local::timegm
0000s0sTime::Local::::timegm_modernTime::Local::timegm_modern
0000s0sTime::Local::::timegm_nocheckTime::Local::timegm_nocheck
0000s0sTime::Local::::timegm_posixTime::Local::timegm_posix
0000s0sTime::Local::::timelocalTime::Local::timelocal
0000s0sTime::Local::::timelocal_modernTime::Local::timelocal_modern
0000s0sTime::Local::::timelocal_nocheckTime::Local::timelocal_nocheck
0000s0sTime::Local::::timelocal_posixTime::Local::timelocal_posix
Call graph for these subroutines as a Graphviz dot language file.
Line State
ments
Time
on line
Calls Time
in subs
Code
1package Time::Local;
2
3217µs212µs
# spent 10µs (9+2) within Time::Local::BEGIN@3 which was called: # once (9µs+2µs) by Archive::Zip::Member::BEGIN@27 at line 3
use strict;
# spent 10µs making 1 call to Time::Local::BEGIN@3 # spent 2µs making 1 call to strict::import
4
5215µs12µs
# spent 2µs within Time::Local::BEGIN@5 which was called: # once (2µs+0s) by Archive::Zip::Member::BEGIN@27 at line 5
use Carp ();
# spent 2µs making 1 call to Time::Local::BEGIN@5
6220µs222µs
# spent 12µs (3+9) within Time::Local::BEGIN@6 which was called: # once (3µs+9µs) by Archive::Zip::Member::BEGIN@27 at line 6
use Exporter;
# spent 12µs making 1 call to Time::Local::BEGIN@6 # spent 9µs making 1 call to Exporter::import
7
81200nsour $VERSION = '1.35';
9
10260µs221µs
# spent 12µs (3+9) within Time::Local::BEGIN@10 which was called: # once (3µs+9µs) by Archive::Zip::Member::BEGIN@27 at line 10
use parent 'Exporter';
# spent 12µs making 1 call to Time::Local::BEGIN@10 # spent 9µs making 1 call to parent::import
11
121700nsour @EXPORT = qw( timegm timelocal );
131500nsour @EXPORT_OK = qw(
14 timegm_modern
15 timelocal_modern
16 timegm_nocheck
17 timelocal_nocheck
18 timegm_posix
19 timelocal_posix
20);
21
221500nsmy @MonthDays = ( 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 );
23
24# Determine breakpoint for rolling century
25110µsmy $ThisYear = ( localtime() )[5];
261900nsmy $Breakpoint = ( $ThisYear + 50 ) % 100;
271300nsmy $NextCentury = $ThisYear - $ThisYear % 100;
281100ns$NextCentury += 100 if $Breakpoint < 50;
291100nsmy $Century = $NextCentury - 100;
3010smy $SecOff = 0;
31
321100nsmy ( %Options, %Cheat );
33
34218µs245µs
# spent 24µs (3+21) within Time::Local::BEGIN@34 which was called: # once (3µs+21µs) by Archive::Zip::Member::BEGIN@27 at line 34
use constant SECS_PER_MINUTE => 60;
# spent 24µs making 1 call to Time::Local::BEGIN@34 # spent 21µs making 1 call to constant::import
35212µs234µs
# spent 19µs (3+16) within Time::Local::BEGIN@35 which was called: # once (3µs+16µs) by Archive::Zip::Member::BEGIN@27 at line 35
use constant SECS_PER_HOUR => 3600;
# spent 19µs making 1 call to Time::Local::BEGIN@35 # spent 16µs making 1 call to constant::import
362628µs230µs
# spent 16µs (2+14) within Time::Local::BEGIN@36 which was called: # once (2µs+14µs) by Archive::Zip::Member::BEGIN@27 at line 36
use constant SECS_PER_DAY => 86400;
# spent 16µs making 1 call to Time::Local::BEGIN@36 # spent 14µs making 1 call to constant::import
37
38my $MaxDay;
391300nsif ( $] < 5.012000 ) {
40 require Config;
41 ## no critic (Variables::ProhibitPackageVars)
42
43 my $MaxInt;
44 if ( $^O eq 'MacOS' ) {
45
46 # time_t is unsigned...
47 $MaxInt = ( 1 << ( 8 * $Config::Config{ivsize} ) )
48 - 1; ## no critic qw(ProhibitPackageVars)
49 }
50 else {
51 $MaxInt
52 = ( ( 1 << ( 8 * $Config::Config{ivsize} - 2 ) ) - 1 ) * 2
53 + 1; ## no critic qw(ProhibitPackageVars)
54 }
55
56 $MaxDay = int( ( $MaxInt - ( SECS_PER_DAY / 2 ) ) / SECS_PER_DAY ) - 1;
57}
58else {
59 # recent localtime()'s limit is the year 2**31
601100ns $MaxDay = 365 * ( 2**31 );
61
62 # On (some?) 32-bit platforms this overflows and we end up with a negative
63 # $MaxDay, which totally breaks this module. This is the old calculation
64 # we used from the days before Perl always had 64-bit time_t.
651100ns if ( $MaxDay < 0 ) {
66 require Config;
67 ## no critic (Variables::ProhibitPackageVars)
68 my $max_int
69 = ( ( 1 << ( 8 * $Config::Config{intsize} - 2 ) ) - 1 ) * 2 + 1;
70 $MaxDay
71 = int( ( $max_int - ( SECS_PER_DAY / 2 ) ) / SECS_PER_DAY ) - 1;
72 }
73}
74
75# Determine the EPOC day for this machine
761100nsmy $Epoc = 0;
7711µsif ( $^O eq 'vos' ) {
78
79 # work around posix-977 -- VOS doesn't handle dates in the range
80 # 1970-1980.
81 $Epoc = _daygm( 0, 0, 0, 1, 0, 70, 4, 0 );
82}
83elsif ( $^O eq 'MacOS' ) {
84 $MaxDay *= 2; # time_t unsigned ... quick hack?
85 # MacOS time() is seconds since 1 Jan 1904, localtime
86 # so we need to calculate an offset to apply later
87 $Epoc = 693901;
88 $SecOff = timelocal( localtime(0) ) - timelocal( gmtime(0) );
89 $Epoc += _daygm( gmtime(0) );
90}
91else {
9213µs110µs $Epoc = _daygm( gmtime(0) );
# spent 10µs making 1 call to Time::Local::_daygm
93}
94
951500ns%Cheat = (); # clear the cache as epoc has changed
96
97
# spent 10µs (8+1) within Time::Local::_daygm which was called: # once (8µs+1µs) by Archive::Zip::Member::BEGIN@27 at line 92
sub _daygm {
98
99 # This is written in such a byzantine way in order to avoid
100 # lexical variables and sub calls, for speed
101 return $_[3] + (
10218µs11µs $Cheat{ pack( 'ss', @_[ 4, 5 ] ) } ||= do {
# spent 1µs making 1 call to CORE::pack
1031300ns my $month = ( $_[4] + 10 ) % 12;
1041700ns my $year = $_[5] + 1900 - int( $month / 10 );
105
10612µs ( ( 365 * $year )
107 + int( $year / 4 )
108 - int( $year / 100 )
109 + int( $year / 400 )
110 + int( ( ( $month * 306 ) + 5 ) / 10 ) )
111 - $Epoc;
112 }
113 );
114}
115
116sub _timegm {
117 my $sec
118 = $SecOff + $_[0]
119 + ( SECS_PER_MINUTE * $_[1] )
120 + ( SECS_PER_HOUR * $_[2] );
121
122 return $sec + ( SECS_PER_DAY * &_daygm );
123}
124
125sub timegm {
126 my ( $sec, $min, $hour, $mday, $month, $year ) = @_;
127 my $subsec = $sec - int($sec);
128 $sec = int($sec);
129
130 if ( $Options{no_year_munging} ) {
131 $year -= 1900;
132 }
133 elsif ( !$Options{posix_year} ) {
134 if ( $year >= 1000 ) {
135 $year -= 1900;
136 }
137 elsif ( $year < 100 and $year >= 0 ) {
138 $year += ( $year > $Breakpoint ) ? $Century : $NextCentury;
139 }
140 }
141
142 unless ( $Options{no_range_check} ) {
143 Carp::croak("Month '$month' out of range 0..11")
144 if $month > 11
145 or $month < 0;
146
147 my $md = $MonthDays[$month];
148 ++$md
149 if $month == 1 && _is_leap_year( $year + 1900 );
150
151 Carp::croak("Day '$mday' out of range 1..$md")
152 if $mday > $md or $mday < 1;
153 Carp::croak("Hour '$hour' out of range 0..23")
154 if $hour > 23 or $hour < 0;
155 Carp::croak("Minute '$min' out of range 0..59")
156 if $min > 59 or $min < 0;
157 Carp::croak("Second '$sec' out of range 0..59")
158 if $sec >= 60 or $sec < 0;
159 }
160
161 my $days = _daygm( undef, undef, undef, $mday, $month, $year );
162
163 if ( abs($days) > $MaxDay && !$Options{no_range_check} ) {
164 my $msg = "Day too big - abs($days) > $MaxDay\n";
165
166 $year += 1900;
167 $msg
168 .= "Cannot handle date ($sec, $min, $hour, $mday, $month, $year)";
169
170 Carp::croak($msg);
171 }
172
173 # Adding in the $subsec value last seems to prevent floating point errors
174 # from creeping in.
175 return (
176 (
177 $sec + $SecOff
178 + ( SECS_PER_MINUTE * $min )
179 + ( SECS_PER_HOUR * $hour )
180 + ( SECS_PER_DAY * $days )
181 ) + $subsec
182 );
183}
184
185sub _is_leap_year {
186 return 0 if $_[0] % 4;
187 return 1 if $_[0] % 100;
188 return 0 if $_[0] % 400;
189
190 return 1;
191}
192
193sub timegm_nocheck {
194 local $Options{no_range_check} = 1;
195 return &timegm;
196}
197
198sub timegm_modern {
199 local $Options{no_year_munging} = 1;
200 return &timegm;
201}
202
203sub timegm_posix {
204 local $Options{posix_year} = 1;
205 return &timegm;
206}
207
208sub timelocal {
209 my $sec = shift;
210 my $subsec = $sec - int($sec);
211 $sec = int($sec);
212 unshift @_, $sec;
213
214 my $ref_t = &timegm;
215 my $loc_for_ref_t = _timegm( localtime($ref_t) );
216
217 my $zone_off = $loc_for_ref_t - $ref_t
218 or return $loc_for_ref_t + $subsec;
219
220 # Adjust for timezone
221 my $loc_t = $ref_t - $zone_off;
222
223 # Are we close to a DST change or are we done
224 my $dst_off = $ref_t - _timegm( localtime($loc_t) );
225
226 # If this evaluates to true, it means that the value in $loc_t is
227 # the _second_ hour after a DST change where the local time moves
228 # backward.
229 if (
230 !$dst_off
231 && ( ( $ref_t - SECS_PER_HOUR )
232 - _timegm( localtime( $loc_t - SECS_PER_HOUR ) ) < 0 )
233 ) {
234 return ( $loc_t - SECS_PER_HOUR ) + $subsec;
235 }
236
237 # Adjust for DST change
238 $loc_t += $dst_off;
239
240 return $loc_t + $subsec if $dst_off > 0;
241
242 # If the original date was a non-existent gap in a forward DST jump, we
243 # should now have the wrong answer - undo the DST adjustment
244 my ( $s, $m, $h ) = localtime($loc_t);
245 $loc_t -= $dst_off if $s != $_[0] || $m != $_[1] || $h != $_[2];
246
247 return $loc_t + $subsec;
248}
249
250sub timelocal_nocheck {
251 local $Options{no_range_check} = 1;
252 return &timelocal;
253}
254
255sub timelocal_modern {
256 local $Options{no_year_munging} = 1;
257 return &timelocal;
258}
259
260sub timelocal_posix {
261 local $Options{posix_year} = 1;
262 return &timelocal;
263}
264
265111µs1;
266
267# ABSTRACT: Efficiently compute time from local and GMT time
268
269__END__