File Coverage

blib/lib/Math/Calc/Units/Convert/Time.pm
Criterion Covered Total %
statement 52 61 85.2
branch 22 26 84.6
condition 0 3 0.0
subroutine 13 15 86.6
pod 0 12 0.0
total 87 117 74.3


line stmt bran cond sub pod time code
1             package Math::Calc::Units::Convert::Time;
2 1     1   5 use base 'Math::Calc::Units::Convert::Metric';
  1         2  
  1         710  
3 1     1   6 use strict;
  1         2  
  1         28  
4 1     1   4 use vars qw(%units %pref %ranges %total_unit_map);
  1         2  
  1         989  
5              
6             %units = ( minute => [ 60, 'sec' ],
7             hour => [ 60, 'minute' ],
8             day => [ 24, 'hour' ],
9             week => [ 7, 'day' ],
10             year => [ 365, 'day' ], # Inexact unit... ugh...
11             );
12              
13             %pref = ( default => 1,
14             hour => 0.8,
15             day => 0.8,
16             week => 0.4,
17             minute => 0.9,
18             year => 0.9,
19             );
20              
21             %ranges = ( default => [ 1, 300 ],
22             millisec => [ 1, 999 ],
23             sec => [ 1, 200 ],
24             minute => [ 2, 100 ],
25             hour => [ 1, 80 ],
26             day => [ 1, 500 ],
27             week => [ 1, 4 ],
28             year => [ 1, undef ],
29             );
30              
31             sub major_pref {
32 2     2 0 12 return 2;
33             }
34              
35             sub major_variants {
36 2     2 0 5 my ($self) = @_;
37 2 100       10 return grep { ($_ ne 'default') && ($_ ne 'week') } keys %ranges;
  16         66  
38             }
39              
40             # Return a list of the variants of the canonical unit of time: 'sec'
41             sub variants {
42 3     3 0 7 my ($self, $base) = @_;
43 3         36 return 'sec', (keys %units), map { "${_}sec" } $self->get_prefixes({ small => 1 });
  18         44  
44             }
45              
46             sub unit_map {
47 154     154 0 209 my ($self) = @_;
48 154 100       354 if (keys %total_unit_map == 0) {
49 1         2 %total_unit_map = (%{$self->SUPER::unit_map()}, %units);
  1         13  
50             }
51 154         384 return \%total_unit_map;
52             }
53              
54 785     785 0 1949 sub canonical_unit { return 'sec'; }
55              
56 0     0 0 0 sub abbreviated_canonical_unit { return 's'; }
57              
58             # demetric : string => [ mult, base ]
59             #
60             # Must override here to avoid megahours or milliweeks
61             #
62             sub demetric {
63 440     440 0 545 my ($self, $string) = @_;
64 440 100       1231 if (my $prefix = $self->get_prefix($string)) {
65 54         110 my $tail = substr($string, length($prefix));
66 54 100       188 if ($tail =~ /^sec(ond)?s?$/) {
67 30         117 return ($self->get_metric($prefix), "sec");
68             }
69 24         129 return; # Should this fail, or assume it's a non-metric unit?
70             } else {
71 386         1517 return (1, $string);
72             }
73             }
74              
75             # simple_convert : unitName x unitName -> multiplier
76             #
77             # Does not allow msec (only millisec or ms)
78             #
79             sub simple_convert {
80 232     232 0 369 my ($self, $from, $to) = @_;
81              
82             # sec, secs, second, seconds
83 232 100       724 $from = "sec" if $from =~ /^sec(ond)?s?$/i;
84 232 100       688 $from = "minute" if $from =~ /^min(ute)?s?$/i;
85              
86 232 100       866 if (my $easy = $self->SUPER::simple_convert($from, $to)) {
87 178         449 return $easy;
88             }
89              
90             # ms == millisec
91 54 100       130 if ($from =~ /^(.)s$/) {
92 3         18 my ($expansion) = $self->expand($1);
93 3         13 return $self->simple_convert($expansion . "sec", $to);
94             }
95              
96 51         115 return; # Failed
97             }
98              
99             ##############################################################################
100              
101             sub preference {
102 0     0 0 0 my ($self, $v) = @_;
103 0         0 my ($val, $unit) = @$v;
104 0         0 my $base = lc(($self->demetric($unit))[1]);
105 0   0     0 my $pref = $pref{$base} || $pref{default};
106 0         0 return $pref * $self->prefix_pref(substr($unit, 0, -length($base)));
107             }
108              
109             sub get_ranges {
110 36     36 0 87 return \%ranges;
111             }
112              
113             sub get_prefs {
114 48     48 0 121 return \%pref;
115             }
116              
117             my @BREAKDOWN = qw(year week day hour minute sec ms us ns ps);
118             sub render {
119 13     13 0 27 my ($self, $val, $name, $power, $options) = @_;
120 13         22 my $full_name = $name;
121 13 100       41 if ($options->{abbreviate}) {
122 3 50       14 if ($name =~ /(\w+)sec/) {
123 0         0 my $prefix = $1;
124 0         0 my $mabbrev = $self->metric_abbreviation($prefix);
125 0 0       0 $name = $mabbrev . "s" unless $mabbrev eq $prefix;
126             }
127             }
128 13         72 my $basic = $self->SUPER::render($val, $name, $power, $options);
129 13 50       42 return $basic if $power != 1;
130              
131 13         42 $val *= $self->simple_convert($full_name, 'sec');
132 13         69 my @spread = $self->spread($val, 'sec', $name, \@BREAKDOWN);
133 13         31 my $spread = join(" ", map { "$_->[0] $_->[1]" } @spread);
  17         80  
134              
135 13 100       63 return "($basic = $spread)" if @spread > 1;
136 8         37 return $basic;
137             }
138              
139             1;