| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | package Time::Duration::Parse; | 
| 2 |  |  |  |  |  |  | $Time::Duration::Parse::VERSION = '0.16'; | 
| 3 | 3 |  |  | 3 |  | 212891 | use 5.006; | 
|  | 3 |  |  |  |  | 31 |  | 
| 4 | 3 |  |  | 3 |  | 18 | use strict; | 
|  | 3 |  |  |  |  | 6 |  | 
|  | 3 |  |  |  |  | 73 |  | 
| 5 | 3 |  |  | 3 |  | 15 | use warnings; | 
|  | 3 |  |  |  |  | 11 |  | 
|  | 3 |  |  |  |  | 104 |  | 
| 6 |  |  |  |  |  |  |  | 
| 7 | 3 |  |  | 3 |  | 20 | use Carp; | 
|  | 3 |  |  |  |  | 3 |  | 
|  | 3 |  |  |  |  | 229 |  | 
| 8 | 3 |  |  | 3 |  | 19 | use Exporter 5.57 qw(import); | 
|  | 3 |  |  |  |  | 70 |  | 
|  | 3 |  |  |  |  | 1772 |  | 
| 9 |  |  |  |  |  |  | our @EXPORT = qw( parse_duration ); | 
| 10 |  |  |  |  |  |  |  | 
| 11 |  |  |  |  |  |  | # This map is taken from Cache and Cache::Cache | 
| 12 |  |  |  |  |  |  | # map of expiration formats to their respective time in seconds | 
| 13 |  |  |  |  |  |  | my %Units = ( map(($_,             1), qw(s second seconds sec secs)), | 
| 14 |  |  |  |  |  |  | map(($_,            60), qw(m minute minutes min mins)), | 
| 15 |  |  |  |  |  |  | map(($_,         60*60), qw(h hr hrs hour hours)), | 
| 16 |  |  |  |  |  |  | map(($_,      60*60*24), qw(d day days)), | 
| 17 |  |  |  |  |  |  | map(($_,    60*60*24*7), qw(w week weeks)), | 
| 18 |  |  |  |  |  |  | map(($_,   60*60*24*30), qw(M month months mo mon mons)), | 
| 19 |  |  |  |  |  |  | map(($_,  60*60*24*365), qw(y year years)) ); | 
| 20 |  |  |  |  |  |  |  | 
| 21 |  |  |  |  |  |  | sub parse_duration { | 
| 22 | 2050 |  |  | 2050 | 1 | 1229954 | my $timespec = shift; | 
| 23 |  |  |  |  |  |  |  | 
| 24 |  |  |  |  |  |  | # You can have an optional leading '+', which has no effect | 
| 25 | 2050 |  |  |  |  | 4709 | $timespec =~ s/^\s*\+\s*//; | 
| 26 |  |  |  |  |  |  |  | 
| 27 |  |  |  |  |  |  | # Treat a plain number as a number of seconds (and parse it later) | 
| 28 | 2050 | 100 |  |  |  | 10676 | if ($timespec =~ /^\s*(-?\d+(?:[.,]\d+)?)\s*$/) { | 
| 29 | 5 |  |  |  |  | 17 | $timespec = "$1s"; | 
| 30 |  |  |  |  |  |  | } | 
| 31 |  |  |  |  |  |  |  | 
| 32 |  |  |  |  |  |  | # Convert hh:mm(:ss)? to something we understand | 
| 33 | 2050 |  |  |  |  | 3686 | $timespec =~ s/\b(\d+):(\d\d):(\d\d(\.\d+)?)\b/$1h $2m $3s/g; | 
| 34 | 2050 |  |  |  |  | 2967 | $timespec =~ s/\b(\d+):(\d\d)\b/$1h $2m/g; | 
| 35 |  |  |  |  |  |  |  | 
| 36 | 2050 |  |  |  |  | 3634 | my $duration = 0; | 
| 37 | 2050 |  |  |  |  | 10938 | while ($timespec =~ s/^\s*(-?\d+(?:[.,]\d+)?)\s*([a-zA-Z]+)(?:\s*(?:,|and)\s*)*//i) { | 
| 38 | 6184 |  |  |  |  | 16752 | my($amount, $unit) = ($1, $2); | 
| 39 | 6184 | 100 |  |  |  | 12734 | $unit = lc($unit) unless length($unit) == 1; | 
| 40 |  |  |  |  |  |  |  | 
| 41 | 6184 | 100 |  |  |  | 12736 | if (my $value = $Units{$unit}) { | 
| 42 | 6182 |  |  |  |  | 9529 | $amount =~ s/,/./; | 
| 43 | 6182 |  |  |  |  | 26507 | $duration += $amount * $value; | 
| 44 |  |  |  |  |  |  | } else { | 
| 45 | 2 |  |  |  |  | 258 | Carp::croak "Unknown timespec: $1 $2"; | 
| 46 |  |  |  |  |  |  | } | 
| 47 |  |  |  |  |  |  | } | 
| 48 |  |  |  |  |  |  |  | 
| 49 | 2048 | 100 |  |  |  | 4088 | if ($timespec =~ /\S/) { | 
| 50 | 1 |  |  |  |  | 85 | Carp::croak "Unknown timespec: $timespec"; | 
| 51 |  |  |  |  |  |  | } | 
| 52 |  |  |  |  |  |  |  | 
| 53 | 2047 |  |  |  |  | 11107 | return sprintf "%.0f", $duration; | 
| 54 |  |  |  |  |  |  | } | 
| 55 |  |  |  |  |  |  |  | 
| 56 |  |  |  |  |  |  | 1; | 
| 57 |  |  |  |  |  |  | __END__ |