File Coverage

blib/lib/Dancer2/Core/Time.pm
Criterion Covered Total %
statement 37 37 100.0
branch 15 16 93.7
condition n/a
subroutine 6 6 100.0
pod 0 1 0.0
total 58 60 96.6


line stmt bran cond sub pod time code
1             package Dancer2::Core::Time;
2             # ABSTRACT: class to handle common helpers for time manipulations
3             $Dancer2::Core::Time::VERSION = '2.0.1';
4 170     170   761937 use Moo;
  170         14864  
  170         1578  
5              
6             has seconds => (
7             is => 'ro',
8             lazy => 1,
9             builder => '_build_seconds',
10             );
11              
12             sub _build_seconds {
13 32     32   563 my ($self) = @_;
14 32         101 my $seconds = $self->expression;
15              
16 32 50       143 return $seconds
17             if $seconds =~ /^\d+$/;
18              
19 32         92 return $self->_parse_duration($seconds)
20             }
21              
22             has epoch => (
23             is => 'ro',
24             lazy => 1,
25             builder => '_build_epoch',
26             );
27              
28             sub _build_epoch {
29 31     31   379 my ($self) = @_;
30 31 100       693 return $self->seconds if $self->seconds !~ /^[\-\+]?\d+$/;
31 25         682 $self->seconds + time;
32             }
33              
34             has gmt_string => (
35             is => 'ro',
36             builder => '_build_gmt_string',
37             lazy => 1,
38             );
39              
40             sub _build_gmt_string {
41 60     60   9868 my ($self) = @_;
42 60         1295 my $epoch = $self->epoch;
43 60 100       895 return $epoch if $epoch !~ /^\d+$/;
44              
45 54         351 my ( $sec, $min, $hour, $mday, $mon, $year, $wday ) = gmtime($epoch);
46 54         326 my @months = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec);
47 54         179 my @days = qw(Sun Mon Tue Wed Thu Fri Sat);
48              
49 54         1668 return sprintf "%s, %02d-%s-%d %02d:%02d:%02d GMT",
50             $days[$wday],
51             $mday,
52             $months[$mon],
53             ( $year + 1900 ),
54             $hour, $min, $sec;
55             }
56              
57             has expression => (
58             is => 'ro',
59             required => 1,
60             );
61              
62             sub BUILDARGS {
63 79     79 0 39835 my ($class, %args) = @_;
64              
65             $args{epoch} = $args{expression}
66 79 100       640 if $args{expression} =~ /^\d+$/;
67              
68 79         1597 return \%args;
69             }
70              
71             # private
72              
73             # This map is taken from Cache and Cache::Cache
74             # map of expiration formats to their respective time in seconds
75             #<<< no perl tidy
76             my %Units = ( map(($_, 1), qw(s second seconds sec secs)),
77             map(($_, 60), qw(m minute minutes min mins)),
78             map(($_, 60*60), qw(h hr hour hours)),
79             map(($_, 60*60*24), qw(d day days)),
80             map(($_, 60*60*24*7), qw(w week weeks)),
81             map(($_, 60*60*24*30), qw(M month months)),
82             map(($_, 60*60*24*365), qw(y year years)) );
83             #>>>
84              
85             # This code is taken from Time::Duration::Parse, except if it isn't
86             # understood it just passes it through and it adds the current time.
87             sub _parse_duration {
88 32     32   71 my ( $self, $timespec ) = @_;
89 32         57 my $orig_timespec = $timespec;
90              
91             # Treat a plain number as a number of seconds (and parse it later)
92 32 100       166 if ( $timespec =~ /^\s*([-+]?\d+(?:[.,]\d+)?)\s*$/ ) {
93 2         10 $timespec = "$1s";
94             }
95              
96             # Convert hh:mm(:ss)? to something we understand
97 32         66 $timespec =~ s/\b(\d+):(\d\d):(\d\d)\b/$1h $2m $3s/g;
98 32         53 $timespec =~ s/\b(\d+):(\d\d)\b/$1h $2m/g;
99              
100 32         52 my $duration = 0;
101 32         216 while ( $timespec
102             =~ s/^\s*([-+]?\d+(?:[.,]\d+)?)\s*([a-zA-Z]+)(?:\s*(?:,|and)\s*)*//i )
103             {
104 37         132 my ( $amount, $unit ) = ( $1, $2 );
105 37 100       122 $unit = lc($unit) unless length($unit) == 1;
106              
107 37 100       122 if ( my $value = $Units{$unit} ) {
108 34         65 $amount =~ s/,/./;
109 34         165 $duration += $amount * $value;
110             }
111             else {
112 3         70 return $orig_timespec;
113             }
114             }
115              
116 29 100       76 if ( $timespec =~ /\S/ ) {
117 3         76 return $orig_timespec;
118             }
119              
120 26         273 return sprintf "%.0f", $duration;
121             }
122              
123             1;
124              
125             __END__