| 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 | HTTP::Date::BEGIN@10 |
| 1 | 1 | 1 | 7µs | 61µs | HTTP::Date::BEGIN@13 |
| 0 | 0 | 0 | 0s | 0s | HTTP::Date::parse_date |
| 0 | 0 | 0 | 0s | 0s | HTTP::Date::str2time |
| 0 | 0 | 0 | 0s | 0s | HTTP::Date::time2iso |
| 0 | 0 | 0 | 0s | 0s | HTTP::Date::time2isoz |
| 0 | 0 | 0 | 0s | 0s | HTTP::Date::time2str |
| 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__ |