← Index
NYTProf Performance Profile   « line view »
For /usr/local/libexec/sympa/task_manager-debug.pl
  Run on Tue Jun 1 22:32:51 2021
Reported on Tue Jun 1 22:35:07 2021

Filename/usr/local/lib/perl5/5.32/Time/Local.pm
StatementsExecuted 0 statements in 0s
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
0000s0sTime::Local::::BEGIN@10Time::Local::BEGIN@10
0000s0sTime::Local::::BEGIN@28Time::Local::BEGIN@28
0000s0sTime::Local::::BEGIN@29Time::Local::BEGIN@29
0000s0sTime::Local::::BEGIN@3Time::Local::BEGIN@3
0000s0sTime::Local::::BEGIN@30Time::Local::BEGIN@30
0000s0sTime::Local::::BEGIN@5Time::Local::BEGIN@5
0000s0sTime::Local::::BEGIN@6Time::Local::BEGIN@6
0000s0sTime::Local::::CORE:packTime::Local::CORE:pack (opcode)
0000s0sTime::Local::::_daygmTime::Local::_daygm
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::::timelocalTime::Local::timelocal
0000s0sTime::Local::::timelocal_modernTime::Local::timelocal_modern
0000s0sTime::Local::::timelocal_nocheckTime::Local::timelocal_nocheck
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
3use strict;
4
5use Carp ();
6use Exporter;
7
8our $VERSION = '1.28';
9
10use parent 'Exporter';
11
12our @EXPORT = qw( timegm timelocal );
13our @EXPORT_OK
14 = qw( timegm_modern timelocal_modern timegm_nocheck timelocal_nocheck );
15
16my @MonthDays = ( 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 );
17
18# Determine breakpoint for rolling century
19my $ThisYear = ( localtime() )[5];
20my $Breakpoint = ( $ThisYear + 50 ) % 100;
21my $NextCentury = $ThisYear - $ThisYear % 100;
22$NextCentury += 100 if $Breakpoint < 50;
23my $Century = $NextCentury - 100;
24my $SecOff = 0;
25
26my ( %Options, %Cheat );
27
28use constant SECS_PER_MINUTE => 60;
29use constant SECS_PER_HOUR => 3600;
30use constant SECS_PER_DAY => 86400;
31
32my $MaxDay;
33if ( $] < 5.012000 ) {
34 require Config;
35 ## no critic (Variables::ProhibitPackageVars)
36
37 my $MaxInt;
38 if ( $^O eq 'MacOS' ) {
39
40 # time_t is unsigned...
41 $MaxInt = ( 1 << ( 8 * $Config::Config{ivsize} ) )
42 - 1; ## no critic qw(ProhibitPackageVars)
43 }
44 else {
45 $MaxInt
46 = ( ( 1 << ( 8 * $Config::Config{ivsize} - 2 ) ) - 1 ) * 2
47 + 1; ## no critic qw(ProhibitPackageVars)
48 }
49
50 $MaxDay = int( ( $MaxInt - ( SECS_PER_DAY / 2 ) ) / SECS_PER_DAY ) - 1;
51}
52else {
53 # recent localtime()'s limit is the year 2**31
54 $MaxDay = 365 * ( 2**31 );
55}
56
57# Determine the EPOC day for this machine
58my $Epoc = 0;
59if ( $^O eq 'vos' ) {
60
61 # work around posix-977 -- VOS doesn't handle dates in the range
62 # 1970-1980.
63 $Epoc = _daygm( 0, 0, 0, 1, 0, 70, 4, 0 );
64}
65elsif ( $^O eq 'MacOS' ) {
66 $MaxDay *= 2; # time_t unsigned ... quick hack?
67 # MacOS time() is seconds since 1 Jan 1904, localtime
68 # so we need to calculate an offset to apply later
69 $Epoc = 693901;
70 $SecOff = timelocal( localtime(0) ) - timelocal( gmtime(0) );
71 $Epoc += _daygm( gmtime(0) );
72}
73else {
74 $Epoc = _daygm( gmtime(0) );
75}
76
77%Cheat = (); # clear the cache as epoc has changed
78
79sub _daygm {
80
81 # This is written in such a byzantine way in order to avoid
82 # lexical variables and sub calls, for speed
83 return $_[3] + (
84 $Cheat{ pack( 'ss', @_[ 4, 5 ] ) } ||= do {
85 my $month = ( $_[4] + 10 ) % 12;
86 my $year = $_[5] + 1900 - int( $month / 10 );
87
88 ( ( 365 * $year )
89 + int( $year / 4 )
90 - int( $year / 100 )
91 + int( $year / 400 )
92 + int( ( ( $month * 306 ) + 5 ) / 10 ) ) - $Epoc;
93 }
94 );
95}
96
97sub _timegm {
98 my $sec
99 = $SecOff + $_[0]
100 + ( SECS_PER_MINUTE * $_[1] )
101 + ( SECS_PER_HOUR * $_[2] );
102
103 return $sec + ( SECS_PER_DAY * &_daygm );
104}
105
106sub timegm {
107 my ( $sec, $min, $hour, $mday, $month, $year ) = @_;
108
109 if ( $Options{no_year_munging} ) {
110 $year -= 1900;
111 }
112 else {
113 if ( $year >= 1000 ) {
114 $year -= 1900;
115 }
116 elsif ( $year < 100 and $year >= 0 ) {
117 $year += ( $year > $Breakpoint ) ? $Century : $NextCentury;
118 }
119 }
120
121 unless ( $Options{no_range_check} ) {
122 Carp::croak("Month '$month' out of range 0..11")
123 if $month > 11
124 or $month < 0;
125
126 my $md = $MonthDays[$month];
127 ++$md
128 if $month == 1 && _is_leap_year( $year + 1900 );
129
130 Carp::croak("Day '$mday' out of range 1..$md")
131 if $mday > $md or $mday < 1;
132 Carp::croak("Hour '$hour' out of range 0..23")
133 if $hour > 23 or $hour < 0;
134 Carp::croak("Minute '$min' out of range 0..59")
135 if $min > 59 or $min < 0;
136 Carp::croak("Second '$sec' out of range 0..59")
137 if $sec >= 60 or $sec < 0;
138 }
139
140 my $days = _daygm( undef, undef, undef, $mday, $month, $year );
141
142 unless ( $Options{no_range_check} or abs($days) < $MaxDay ) {
143 my $msg = q{};
144 $msg .= "Day too big - $days > $MaxDay\n" if $days > $MaxDay;
145
146 $year += 1900;
147 $msg
148 .= "Cannot handle date ($sec, $min, $hour, $mday, $month, $year)";
149
150 Carp::croak($msg);
151 }
152
153 return
154 $sec + $SecOff
155 + ( SECS_PER_MINUTE * $min )
156 + ( SECS_PER_HOUR * $hour )
157 + ( SECS_PER_DAY * $days );
158}
159
160sub _is_leap_year {
161 return 0 if $_[0] % 4;
162 return 1 if $_[0] % 100;
163 return 0 if $_[0] % 400;
164
165 return 1;
166}
167
168sub timegm_nocheck {
169 local $Options{no_range_check} = 1;
170 return &timegm;
171}
172
173sub timegm_modern {
174 local $Options{no_year_munging} = 1;
175 return &timegm;
176}
177
178sub timelocal {
179 my $ref_t = &timegm;
180 my $loc_for_ref_t = _timegm( localtime($ref_t) );
181
182 my $zone_off = $loc_for_ref_t - $ref_t
183 or return $loc_for_ref_t;
184
185 # Adjust for timezone
186 my $loc_t = $ref_t - $zone_off;
187
188 # Are we close to a DST change or are we done
189 my $dst_off = $ref_t - _timegm( localtime($loc_t) );
190
191 # If this evaluates to true, it means that the value in $loc_t is
192 # the _second_ hour after a DST change where the local time moves
193 # backward.
194 if (
195 !$dst_off
196 && ( ( $ref_t - SECS_PER_HOUR )
197 - _timegm( localtime( $loc_t - SECS_PER_HOUR ) ) < 0 )
198 ) {
199 return $loc_t - SECS_PER_HOUR;
200 }
201
202 # Adjust for DST change
203 $loc_t += $dst_off;
204
205 return $loc_t if $dst_off > 0;
206
207 # If the original date was a non-extent gap in a forward DST jump,
208 # we should now have the wrong answer - undo the DST adjustment
209 my ( $s, $m, $h ) = localtime($loc_t);
210 $loc_t -= $dst_off if $s != $_[0] || $m != $_[1] || $h != $_[2];
211
212 return $loc_t;
213}
214
215sub timelocal_nocheck {
216 local $Options{no_range_check} = 1;
217 return &timelocal;
218}
219
220sub timelocal_modern {
221 local $Options{no_year_munging} = 1;
222 return &timelocal;
223}
224
2251;
226
227# ABSTRACT: Efficiently compute time from local and GMT time
228
229__END__