| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | package Time::Duration::Parse::AsHash; | 
| 2 |  |  |  |  |  |  |  | 
| 3 |  |  |  |  |  |  | our $DATE = '2016-05-17'; # DATE | 
| 4 |  |  |  |  |  |  | our $VERSION = '0.10.3'; # VERSION | 
| 5 |  |  |  |  |  |  |  | 
| 6 |  |  |  |  |  |  | #IFUNBUILT | 
| 7 | 1 |  |  | 1 |  | 13146 | use strict; | 
|  | 1 |  |  |  |  | 1 |  | 
|  | 1 |  |  |  |  | 52 |  | 
| 8 | 1 |  |  | 1 |  | 4 | use warnings; | 
|  | 1 |  |  |  |  | 1 |  | 
|  | 1 |  |  |  |  | 23 |  | 
| 9 |  |  |  |  |  |  | #IFUNBUILT | 
| 10 |  |  |  |  |  |  |  | 
| 11 | 1 |  |  | 1 |  | 3 | use Exporter; | 
|  | 1 |  |  |  |  | 1 |  | 
|  | 1 |  |  |  |  | 444 |  | 
| 12 |  |  |  |  |  |  | our @ISA    = qw( Exporter ); | 
| 13 |  |  |  |  |  |  | our @EXPORT = qw( parse_duration ); | 
| 14 |  |  |  |  |  |  |  | 
| 15 |  |  |  |  |  |  | my %Units = ( map(($_, "nanoseconds" ), qw(ns nanosecond nanoseconds)), | 
| 16 |  |  |  |  |  |  | map(($_, "milliseconds"), qw(ms millisecond milliseconds milisecond miliseconds)), | 
| 17 |  |  |  |  |  |  | map(($_, "microseconds"), qw(microsecond microseconds)), | 
| 18 |  |  |  |  |  |  | map(($_, "seconds"), qw(s second seconds sec secs)), | 
| 19 |  |  |  |  |  |  | map(($_, "minutes"), qw(m minute minutes min mins)), | 
| 20 |  |  |  |  |  |  | map(($_,   "hours"), qw(h hr hour hours)), | 
| 21 |  |  |  |  |  |  | map(($_,    "days"), qw(d day days)), | 
| 22 |  |  |  |  |  |  | map(($_,   "weeks"), qw(w week weeks)), | 
| 23 |  |  |  |  |  |  | map(($_,  "months"), qw(M month months mon mons mo mos)), | 
| 24 |  |  |  |  |  |  | map(($_,   "years"), qw(y year years)), | 
| 25 |  |  |  |  |  |  | map(($_, "decades"), qw(decade decades)), | 
| 26 |  |  |  |  |  |  | ); | 
| 27 |  |  |  |  |  |  | my %Converts = ( | 
| 28 |  |  |  |  |  |  | nanoseconds  => ["seconds" => 1e-9], | 
| 29 |  |  |  |  |  |  | microseconds => ["seconds" => 1e-6], | 
| 30 |  |  |  |  |  |  | milliseconds => ["seconds" => 1e-3], | 
| 31 |  |  |  |  |  |  | decades      => ["years"   => 10], | 
| 32 |  |  |  |  |  |  | ); | 
| 33 |  |  |  |  |  |  |  | 
| 34 |  |  |  |  |  |  | sub parse_duration { | 
| 35 | 47 |  |  | 47 | 1 | 61 | my $timespec = shift; | 
| 36 |  |  |  |  |  |  |  | 
| 37 |  |  |  |  |  |  | # You can have an optional leading '+', which has no effect | 
| 38 | 47 |  |  |  |  | 71 | $timespec =~ s/^\s*\+\s*//; | 
| 39 |  |  |  |  |  |  |  | 
| 40 |  |  |  |  |  |  | # Treat a plain number as a number of seconds (and parse it later) | 
| 41 | 47 | 100 |  |  |  | 196 | if ($timespec =~ /^\s*(-?\d+(?:[.,]\d+)?)\s*$/) { | 
| 42 | 5 |  |  |  |  | 11 | $timespec = "$1s"; | 
| 43 |  |  |  |  |  |  | } | 
| 44 |  |  |  |  |  |  |  | 
| 45 |  |  |  |  |  |  | # Convert hh:mm(:ss)? to something we understand | 
| 46 | 47 |  |  |  |  | 68 | $timespec =~ s/\b(\d+):(\d\d):(\d\d(?:\.\d+)?)\b/$1h $2m $3s/g; | 
| 47 | 47 |  |  |  |  | 52 | $timespec =~ s/\b(\d+):(\d\d)\b/$1h $2m/g; | 
| 48 |  |  |  |  |  |  |  | 
| 49 | 47 |  |  |  |  | 43 | my %res; | 
| 50 | 47 |  |  |  |  | 209 | while ($timespec =~ s/^\s*(-?\d+(?:[.,]\d+)?)\s*([a-zA-Z]+)(?:\s*(?:,|and)\s*)*//i) { | 
| 51 | 73 |  |  |  |  | 124 | my($amount, $unit) = ($1, $2); | 
| 52 | 73 | 100 |  |  |  | 121 | $unit = lc($unit) unless length($unit) == 1; | 
| 53 |  |  |  |  |  |  |  | 
| 54 | 73 | 100 |  |  |  | 109 | if (my $canon_unit = $Units{$unit}) { | 
| 55 | 71 |  |  |  |  | 64 | $amount =~ s/,/./; | 
| 56 | 71 | 100 |  |  |  | 164 | if (my $convert = $Converts{$canon_unit}) { | 
| 57 | 4 |  |  |  |  | 4 | $canon_unit = $convert->[0]; | 
| 58 | 4 |  |  |  |  | 8 | $amount *= $convert->[1]; | 
| 59 |  |  |  |  |  |  | } | 
| 60 | 71 |  |  |  |  | 258 | $res{$canon_unit} += $amount; | 
| 61 |  |  |  |  |  |  | } else { | 
| 62 | 2 |  |  |  |  | 16 | die "Unknown timespec: $1 $2"; | 
| 63 |  |  |  |  |  |  | } | 
| 64 |  |  |  |  |  |  | } | 
| 65 |  |  |  |  |  |  |  | 
| 66 | 45 | 100 |  |  |  | 64 | if ($timespec =~ /\S/) { | 
| 67 | 1 |  |  |  |  | 7 | die "Unknown timespec: $timespec"; | 
| 68 |  |  |  |  |  |  | } | 
| 69 |  |  |  |  |  |  |  | 
| 70 | 44 |  |  |  |  | 106 | for (keys %res) { | 
| 71 | 68 | 100 |  |  |  | 780 | delete $res{$_} if $res{$_} == 0; | 
| 72 |  |  |  |  |  |  | } | 
| 73 |  |  |  |  |  |  |  | 
| 74 | 44 |  |  |  |  | 115 | \%res; | 
| 75 |  |  |  |  |  |  | } | 
| 76 |  |  |  |  |  |  |  | 
| 77 |  |  |  |  |  |  | 1; | 
| 78 |  |  |  |  |  |  | # ABSTRACT: Parse string that represents time duration | 
| 79 |  |  |  |  |  |  |  | 
| 80 |  |  |  |  |  |  | __END__ |