line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package DateTime::Format::Human::Duration; |
2
|
|
|
|
|
|
|
|
3
|
3
|
|
|
3
|
|
41631
|
use warnings; |
|
3
|
|
|
|
|
3
|
|
|
3
|
|
|
|
|
83
|
|
4
|
3
|
|
|
3
|
|
10
|
use strict; |
|
3
|
|
|
|
|
4
|
|
|
3
|
|
|
|
|
112
|
|
5
|
|
|
|
|
|
|
require DateTime::Format::Human::Duration::Locale; |
6
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
our $VERSION = '0.64'; |
8
|
|
|
|
|
|
|
|
9
|
3
|
|
|
3
|
|
10
|
use Carp qw/croak/; |
|
3
|
|
|
|
|
6
|
|
|
3
|
|
|
|
|
1828
|
|
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
sub new { |
12
|
1
|
|
|
1
|
1
|
19
|
bless { 'locale_cache' => {} }, 'DateTime::Format::Human::Duration'; |
13
|
|
|
|
|
|
|
} |
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
sub format_duration_between { |
16
|
0
|
|
|
0
|
1
|
|
my ($span, $dt, $dtb, %args) = @_; |
17
|
0
|
|
|
|
|
|
my $dur = $dt - $dtb; |
18
|
|
|
|
|
|
|
|
19
|
0
|
0
|
|
|
|
|
if (!exists $args{'locale'}) { |
20
|
0
|
|
|
|
|
|
my $locale_obj = $dt->locale; |
21
|
0
|
0
|
|
|
|
|
if (UNIVERSAL::can($locale_obj, 'code')) { |
22
|
0
|
|
|
|
|
|
$args{'locale'} = $locale_obj->code; # DateTime::Locale v1 |
23
|
|
|
|
|
|
|
} else { |
24
|
0
|
|
|
|
|
|
$args{'locale'} = $locale_obj->id; # DateTime::Locale v0 |
25
|
|
|
|
|
|
|
} |
26
|
|
|
|
|
|
|
} |
27
|
|
|
|
|
|
|
|
28
|
0
|
|
|
|
|
|
return $span->format_duration($dur, %args); |
29
|
|
|
|
|
|
|
} |
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
sub format_duration { |
32
|
0
|
|
|
0
|
1
|
|
my ($span, $duration, %args) = @_; |
33
|
|
|
|
|
|
|
|
34
|
0
|
|
|
|
|
|
my @default_units = qw(years months weeks days hours minutes seconds nanoseconds); |
35
|
|
|
|
|
|
|
|
36
|
0
|
0
|
|
|
|
|
my @units = $args{'units'} ? @{ $args{'units'} } : @default_units; |
|
0
|
|
|
|
|
|
|
37
|
0
|
0
|
|
|
|
|
if ($args{'precision'}) { |
38
|
|
|
|
|
|
|
# Reduce time resolution to requested precision |
39
|
0
|
|
|
|
|
|
for (my $i = 0; $i < scalar(@units); $i++) { |
40
|
0
|
0
|
|
|
|
|
next unless ($units[$i] eq $args{'precision'}); |
41
|
0
|
|
|
|
|
|
splice(@units, $i + 1); |
42
|
|
|
|
|
|
|
} |
43
|
0
|
0
|
|
|
|
|
croak('Useless precision') unless (@units); |
44
|
|
|
|
|
|
|
} |
45
|
|
|
|
|
|
|
|
46
|
0
|
|
|
|
|
|
my @duration_vals = $duration->in_units( @units ); |
47
|
0
|
|
|
|
|
|
my $i = 0; |
48
|
0
|
|
|
|
|
|
my %duration_vals = map { ($_ => $duration_vals[$i++]) } @units; |
|
0
|
|
|
|
|
|
|
49
|
0
|
|
|
|
|
|
my %positive_duration_vals = map { ($_ => abs $duration_vals{$_}) } keys %duration_vals; |
|
0
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
51
|
0
|
|
|
|
|
|
my $say = ''; |
52
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
# $dta - $dtb: |
54
|
|
|
|
|
|
|
# if dta < dtb means past -> future (Duration units will have negatives) |
55
|
|
|
|
|
|
|
# else its either this absolute instant (no_time) or the past |
56
|
0
|
0
|
|
|
|
|
if ( grep { $_ < 0 } @duration_vals ) { |
|
0
|
|
|
|
|
|
|
57
|
0
|
0
|
|
|
|
|
if ( exists $args{'future'} ) { |
58
|
0
|
|
|
|
|
|
$say = $args{'future'} |
59
|
|
|
|
|
|
|
} |
60
|
|
|
|
|
|
|
} |
61
|
|
|
|
|
|
|
else { |
62
|
0
|
0
|
|
|
|
|
if ( exists $args{'past'} ) { |
63
|
0
|
|
|
|
|
|
$say = $args{'past'} |
64
|
|
|
|
|
|
|
} |
65
|
|
|
|
|
|
|
} |
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
#### |
68
|
|
|
|
|
|
|
## this is essentially the hashref that is returned from DateTime::Format::Human::Duration::en::get_human_span_hashref() : # |
69
|
|
|
|
|
|
|
#### |
70
|
0
|
|
|
|
|
|
my $setup = { |
71
|
|
|
|
|
|
|
'no_oxford_comma' => 0, |
72
|
|
|
|
|
|
|
'no_time' => 'no time', # The wait will be $formatted_duration |
73
|
|
|
|
|
|
|
'and' => 'and', |
74
|
|
|
|
|
|
|
'year' => 'year', |
75
|
|
|
|
|
|
|
'years' => 'years', |
76
|
|
|
|
|
|
|
'month' => 'month', |
77
|
|
|
|
|
|
|
'months' => 'months', |
78
|
|
|
|
|
|
|
'week' => 'week', |
79
|
|
|
|
|
|
|
'weeks' => 'weeks', |
80
|
|
|
|
|
|
|
'day' => 'day', |
81
|
|
|
|
|
|
|
'days' => 'days', |
82
|
|
|
|
|
|
|
'hour' => 'hour', |
83
|
|
|
|
|
|
|
'hours' => 'hours', |
84
|
|
|
|
|
|
|
'minute' => 'minute', |
85
|
|
|
|
|
|
|
'minutes' => 'minutes', |
86
|
|
|
|
|
|
|
'second' => 'second', |
87
|
|
|
|
|
|
|
'seconds' => 'seconds', |
88
|
|
|
|
|
|
|
'nanosecond' => 'nanosecond', |
89
|
|
|
|
|
|
|
'nanoseconds' => 'nanoseconds', |
90
|
|
|
|
|
|
|
}; |
91
|
|
|
|
|
|
|
|
92
|
0
|
|
|
|
|
|
my $locale = DateTime::Format::Human::Duration::Locale::calc_locale($span, $args{'locale'}); |
93
|
|
|
|
|
|
|
|
94
|
0
|
0
|
|
|
|
|
if($locale) { |
95
|
0
|
0
|
|
|
|
|
if ( ref $locale eq 'HASH' ) { |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
96
|
0
|
|
|
|
|
|
%{ $setup } = ( |
97
|
0
|
|
|
|
|
|
%{ $setup }, |
98
|
0
|
|
|
|
|
|
%{ $locale }, |
|
0
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
); |
100
|
|
|
|
|
|
|
} |
101
|
|
|
|
|
|
|
# get_human_span_from_units_array is deprecated, but we will still |
102
|
|
|
|
|
|
|
# support it. |
103
|
|
|
|
|
|
|
elsif ( my $get1 = $locale->can('get_human_span_from_units_array') ) { |
104
|
0
|
|
|
|
|
|
my @n = map { $positive_duration_vals{$_} } @default_units; |
|
0
|
|
|
|
|
|
|
105
|
0
|
|
|
|
|
|
return $get1->( @n, \%args ); |
106
|
|
|
|
|
|
|
} |
107
|
|
|
|
|
|
|
elsif ( my $get2 = $locale->can('get_human_span_from_units') ) { |
108
|
0
|
|
|
|
|
|
return $get2->( \%duration_vals, \%args ); |
109
|
|
|
|
|
|
|
} |
110
|
|
|
|
|
|
|
} |
111
|
|
|
|
|
|
|
|
112
|
0
|
|
|
|
|
|
my @parts; |
113
|
0
|
|
|
|
|
|
for my $unit (@units) { |
114
|
0
|
|
|
|
|
|
my $val = $positive_duration_vals{$unit}; |
115
|
0
|
0
|
|
|
|
|
next unless $val; |
116
|
|
|
|
|
|
|
|
117
|
0
|
|
|
|
|
|
my $setup_key = $unit; |
118
|
0
|
0
|
|
|
|
|
if ($val == 1) { |
119
|
0
|
|
|
|
|
|
$setup_key =~ s/s$//; |
120
|
|
|
|
|
|
|
} |
121
|
|
|
|
|
|
|
|
122
|
0
|
|
|
|
|
|
push(@parts, $val . ' ' . $setup->{$setup_key}); |
123
|
0
|
0
|
|
|
|
|
if (exists $args{'significant_units'}) { |
124
|
0
|
0
|
|
|
|
|
last if scalar(@parts) == $args{'significant_units'}; |
125
|
|
|
|
|
|
|
} |
126
|
|
|
|
|
|
|
} |
127
|
|
|
|
|
|
|
|
128
|
0
|
0
|
|
|
|
|
my $no_time = exists $args{'no_time'} ? $args{'no_time'} : $setup->{'no_time'}; |
129
|
0
|
0
|
|
|
|
|
return $no_time if !@parts; |
130
|
|
|
|
|
|
|
|
131
|
0
|
0
|
|
|
|
|
my $last = @parts > 1 ? pop(@parts): ''; |
132
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
## We want to use the so-called Oxford comma to avoid ambiguity. |
134
|
|
|
|
|
|
|
## For that reason we make locale's specifically tell us they do not want it. |
135
|
0
|
0
|
|
|
|
|
my $string = $setup->{'no_oxford_comma'} |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
136
|
|
|
|
|
|
|
? join(', ', @parts) . ($last ? " $setup->{'and'} $last" : '') |
137
|
|
|
|
|
|
|
: join(', ', @parts) . (@parts > 1 ? ',' : '') . ($last ? " $setup->{'and'} $last" : '') |
138
|
|
|
|
|
|
|
; |
139
|
|
|
|
|
|
|
|
140
|
0
|
0
|
|
|
|
|
if ( $say ) { |
141
|
0
|
0
|
|
|
|
|
$string = $say =~ m{%s} ? sprintf($say, $string): "$say $string"; |
142
|
|
|
|
|
|
|
} |
143
|
|
|
|
|
|
|
|
144
|
0
|
|
|
|
|
|
return $string; |
145
|
|
|
|
|
|
|
} |
146
|
|
|
|
|
|
|
|
147
|
|
|
|
|
|
|
1; |
148
|
|
|
|
|
|
|
|
149
|
|
|
|
|
|
|
__END__ |