Filename | /usr/share/perl5/HTTP/Date.pm |
Statements | Executed 15 statements in 1.31ms |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
1 | 1 | 1 | 13µs | 24µs | BEGIN@10 | HTTP::Date::
1 | 1 | 1 | 7µs | 61µs | BEGIN@13 | HTTP::Date::
0 | 0 | 0 | 0s | 0s | parse_date | HTTP::Date::
0 | 0 | 0 | 0s | 0s | str2time | HTTP::Date::
0 | 0 | 0 | 0s | 0s | time2iso | HTTP::Date::
0 | 0 | 0 | 0s | 0s | time2isoz | HTTP::Date::
0 | 0 | 0 | 0s | 0s | time2str | HTTP::Date::
Line | State ments |
Time on line |
Calls | Time in subs |
Code |
---|---|---|---|---|---|
1 | package HTTP::Date; | ||||
2 | |||||
3 | 1 | 400ns | $VERSION = "6.02"; | ||
4 | |||||
5 | 1 | 700ns | require Exporter; | ||
6 | 1 | 7µs | @ISA = qw(Exporter); | ||
7 | 1 | 600ns | @EXPORT = qw(time2str str2time); | ||
8 | 1 | 300ns | @EXPORT_OK = qw(parse_date time2iso time2isoz); | ||
9 | |||||
10 | 2 | 31µs | 2 | 34µs | # spent 24µs (13+11) within HTTP::Date::BEGIN@10 which was called:
# once (13µs+11µs) by LWP::UserAgent::BEGIN@12 at line 10 # spent 24µs making 1 call to HTTP::Date::BEGIN@10
# spent 11µs making 1 call to strict::import |
11 | 1 | 400ns | require Time::Local; | ||
12 | |||||
13 | 2 | 1.25ms | 2 | 115µs | # spent 61µs (7+54) within HTTP::Date::BEGIN@13 which was called:
# once (7µs+54µs) by LWP::UserAgent::BEGIN@12 at line 13 # spent 61µs making 1 call to HTTP::Date::BEGIN@13
# spent 54µs making 1 call to vars::import |
14 | 1 | 600ns | @DoW = qw(Sun Mon Tue Wed Thu Fri Sat); | ||
15 | 1 | 1µs | @MoY = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec); | ||
16 | 1 | 7µs | @MoY{@MoY} = (1..12); | ||
17 | |||||
18 | 1 | 2µs | my %GMT_ZONE = (GMT => 1, UTC => 1, UT => 1, Z => 1); | ||
19 | |||||
20 | |||||
21 | sub time2str (;$) | ||||
22 | { | ||||
23 | my $time = shift; | ||||
24 | $time = time unless defined $time; | ||||
25 | my ($sec, $min, $hour, $mday, $mon, $year, $wday) = gmtime($time); | ||||
26 | sprintf("%s, %02d %s %04d %02d:%02d:%02d GMT", | ||||
27 | $DoW[$wday], | ||||
28 | $mday, $MoY[$mon], $year+1900, | ||||
29 | $hour, $min, $sec); | ||||
30 | } | ||||
31 | |||||
32 | |||||
33 | sub str2time ($;$) | ||||
34 | { | ||||
35 | my $str = shift; | ||||
36 | return undef unless defined $str; | ||||
37 | |||||
38 | # fast exit for strictly conforming string | ||||
39 | if ($str =~ /^[SMTWF][a-z][a-z], (\d\d) ([JFMAJSOND][a-z][a-z]) (\d\d\d\d) (\d\d):(\d\d):(\d\d) GMT$/) { | ||||
40 | return eval { | ||||
41 | my $t = Time::Local::timegm($6, $5, $4, $1, $MoY{$2}-1, $3); | ||||
42 | $t < 0 ? undef : $t; | ||||
43 | }; | ||||
44 | } | ||||
45 | |||||
46 | my @d = parse_date($str); | ||||
47 | return undef unless @d; | ||||
48 | $d[1]--; # month | ||||
49 | |||||
50 | my $tz = pop(@d); | ||||
51 | unless (defined $tz) { | ||||
52 | unless (defined($tz = shift)) { | ||||
53 | return eval { my $frac = $d[-1]; $frac -= ($d[-1] = int($frac)); | ||||
54 | my $t = Time::Local::timelocal(reverse @d) + $frac; | ||||
55 | $t < 0 ? undef : $t; | ||||
56 | }; | ||||
57 | } | ||||
58 | } | ||||
59 | |||||
60 | my $offset = 0; | ||||
61 | if ($GMT_ZONE{uc $tz}) { | ||||
62 | # offset already zero | ||||
63 | } | ||||
64 | elsif ($tz =~ /^([-+])?(\d\d?):?(\d\d)?$/) { | ||||
65 | $offset = 3600 * $2; | ||||
66 | $offset += 60 * $3 if $3; | ||||
67 | $offset *= -1 if $1 && $1 eq '-'; | ||||
68 | } | ||||
69 | else { | ||||
70 | eval { require Time::Zone } || return undef; | ||||
71 | $offset = Time::Zone::tz_offset($tz); | ||||
72 | return undef unless defined $offset; | ||||
73 | } | ||||
74 | |||||
75 | return eval { my $frac = $d[-1]; $frac -= ($d[-1] = int($frac)); | ||||
76 | my $t = Time::Local::timegm(reverse @d) + $frac; | ||||
77 | $t < 0 ? undef : $t - $offset; | ||||
78 | }; | ||||
79 | } | ||||
80 | |||||
81 | |||||
82 | sub parse_date ($) | ||||
83 | { | ||||
84 | local($_) = shift; | ||||
85 | return unless defined; | ||||
86 | |||||
87 | # More lax parsing below | ||||
88 | s/^\s+//; # kill leading space | ||||
89 | s/^(?:Sun|Mon|Tue|Wed|Thu|Fri|Sat)[a-z]*,?\s*//i; # Useless weekday | ||||
90 | |||||
91 | my($day, $mon, $yr, $hr, $min, $sec, $tz, $ampm); | ||||
92 | |||||
93 | # Then we are able to check for most of the formats with this regexp | ||||
94 | (($day,$mon,$yr,$hr,$min,$sec,$tz) = | ||||
95 | /^ | ||||
96 | (\d\d?) # day | ||||
97 | (?:\s+|[-\/]) | ||||
98 | (\w+) # month | ||||
99 | (?:\s+|[-\/]) | ||||
100 | (\d+) # year | ||||
101 | (?: | ||||
102 | (?:\s+|:) # separator before clock | ||||
103 | (\d\d?):(\d\d) # hour:min | ||||
104 | (?::(\d\d))? # optional seconds | ||||
105 | )? # optional clock | ||||
106 | \s* | ||||
107 | ([-+]?\d{2,4}|(?![APap][Mm]\b)[A-Za-z]+)? # timezone | ||||
108 | \s* | ||||
109 | (?:\(\w+\)|\w{3,})? # ASCII representation of timezone. | ||||
110 | \s*$ | ||||
111 | /x) | ||||
112 | |||||
113 | || | ||||
114 | |||||
115 | # Try the ctime and asctime format | ||||
116 | (($mon, $day, $hr, $min, $sec, $tz, $yr) = | ||||
117 | /^ | ||||
118 | (\w{1,3}) # month | ||||
119 | \s+ | ||||
120 | (\d\d?) # day | ||||
121 | \s+ | ||||
122 | (\d\d?):(\d\d) # hour:min | ||||
123 | (?::(\d\d))? # optional seconds | ||||
124 | \s+ | ||||
125 | (?:([A-Za-z]+)\s+)? # optional timezone | ||||
126 | (\d+) # year | ||||
127 | \s*$ # allow trailing whitespace | ||||
128 | /x) | ||||
129 | |||||
130 | || | ||||
131 | |||||
132 | # Then the Unix 'ls -l' date format | ||||
133 | (($mon, $day, $yr, $hr, $min, $sec) = | ||||
134 | /^ | ||||
135 | (\w{3}) # month | ||||
136 | \s+ | ||||
137 | (\d\d?) # day | ||||
138 | \s+ | ||||
139 | (?: | ||||
140 | (\d\d\d\d) | # year | ||||
141 | (\d{1,2}):(\d{2}) # hour:min | ||||
142 | (?::(\d\d))? # optional seconds | ||||
143 | ) | ||||
144 | \s*$ | ||||
145 | /x) | ||||
146 | |||||
147 | || | ||||
148 | |||||
149 | # ISO 8601 format '1996-02-29 12:00:00 -0100' and variants | ||||
150 | (($yr, $mon, $day, $hr, $min, $sec, $tz) = | ||||
151 | /^ | ||||
152 | (\d{4}) # year | ||||
153 | [-\/]? | ||||
154 | (\d\d?) # numerical month | ||||
155 | [-\/]? | ||||
156 | (\d\d?) # day | ||||
157 | (?: | ||||
158 | (?:\s+|[-:Tt]) # separator before clock | ||||
159 | (\d\d?):?(\d\d) # hour:min | ||||
160 | (?::?(\d\d(?:\.\d*)?))? # optional seconds (and fractional) | ||||
161 | )? # optional clock | ||||
162 | \s* | ||||
163 | ([-+]?\d\d?:?(:?\d\d)? | ||||
164 | |Z|z)? # timezone (Z is "zero meridian", i.e. GMT) | ||||
165 | \s*$ | ||||
166 | /x) | ||||
167 | |||||
168 | || | ||||
169 | |||||
170 | # Windows 'dir' 11-12-96 03:52PM | ||||
171 | (($mon, $day, $yr, $hr, $min, $ampm) = | ||||
172 | /^ | ||||
173 | (\d{2}) # numerical month | ||||
174 | - | ||||
175 | (\d{2}) # day | ||||
176 | - | ||||
177 | (\d{2}) # year | ||||
178 | \s+ | ||||
179 | (\d\d?):(\d\d)([APap][Mm]) # hour:min AM or PM | ||||
180 | \s*$ | ||||
181 | /x) | ||||
182 | |||||
183 | || | ||||
184 | return; # unrecognized format | ||||
185 | |||||
186 | # Translate month name to number | ||||
187 | $mon = $MoY{$mon} || | ||||
188 | $MoY{"\u\L$mon"} || | ||||
189 | ($mon =~ /^\d\d?$/ && $mon >= 1 && $mon <= 12 && int($mon)) || | ||||
190 | return; | ||||
191 | |||||
192 | # If the year is missing, we assume first date before the current, | ||||
193 | # because of the formats we support such dates are mostly present | ||||
194 | # on "ls -l" listings. | ||||
195 | unless (defined $yr) { | ||||
196 | my $cur_mon; | ||||
197 | ($cur_mon, $yr) = (localtime)[4, 5]; | ||||
198 | $yr += 1900; | ||||
199 | $cur_mon++; | ||||
200 | $yr-- if $mon > $cur_mon; | ||||
201 | } | ||||
202 | elsif (length($yr) < 3) { | ||||
203 | # Find "obvious" year | ||||
204 | my $cur_yr = (localtime)[5] + 1900; | ||||
205 | my $m = $cur_yr % 100; | ||||
206 | my $tmp = $yr; | ||||
207 | $yr += $cur_yr - $m; | ||||
208 | $m -= $tmp; | ||||
209 | $yr += ($m > 0) ? 100 : -100 | ||||
210 | if abs($m) > 50; | ||||
211 | } | ||||
212 | |||||
213 | # Make sure clock elements are defined | ||||
214 | $hr = 0 unless defined($hr); | ||||
215 | $min = 0 unless defined($min); | ||||
216 | $sec = 0 unless defined($sec); | ||||
217 | |||||
218 | # Compensate for AM/PM | ||||
219 | if ($ampm) { | ||||
220 | $ampm = uc $ampm; | ||||
221 | $hr = 0 if $hr == 12 && $ampm eq 'AM'; | ||||
222 | $hr += 12 if $ampm eq 'PM' && $hr != 12; | ||||
223 | } | ||||
224 | |||||
225 | return($yr, $mon, $day, $hr, $min, $sec, $tz) | ||||
226 | if wantarray; | ||||
227 | |||||
228 | if (defined $tz) { | ||||
229 | $tz = "Z" if $tz =~ /^(GMT|UTC?|[-+]?0+)$/; | ||||
230 | } | ||||
231 | else { | ||||
232 | $tz = ""; | ||||
233 | } | ||||
234 | return sprintf("%04d-%02d-%02d %02d:%02d:%02d%s", | ||||
235 | $yr, $mon, $day, $hr, $min, $sec, $tz); | ||||
236 | } | ||||
237 | |||||
238 | |||||
239 | sub time2iso (;$) | ||||
240 | { | ||||
241 | my $time = shift; | ||||
242 | $time = time unless defined $time; | ||||
243 | my($sec,$min,$hour,$mday,$mon,$year) = localtime($time); | ||||
244 | sprintf("%04d-%02d-%02d %02d:%02d:%02d", | ||||
245 | $year+1900, $mon+1, $mday, $hour, $min, $sec); | ||||
246 | } | ||||
247 | |||||
248 | |||||
249 | sub time2isoz (;$) | ||||
250 | { | ||||
251 | my $time = shift; | ||||
252 | $time = time unless defined $time; | ||||
253 | my($sec,$min,$hour,$mday,$mon,$year) = gmtime($time); | ||||
254 | sprintf("%04d-%02d-%02d %02d:%02d:%02dZ", | ||||
255 | $year+1900, $mon+1, $mday, $hour, $min, $sec); | ||||
256 | } | ||||
257 | |||||
258 | 1 | 7µs | 1; | ||
259 | |||||
260 | |||||
261 | __END__ |