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             # ABSTRACT: class to handle common helpers for time manipulations
2             $Dancer2::Core::Time::VERSION = '0.400000';
3             use Moo;
4 148     148   2773  
  148         5708  
  148         1847  
5             has seconds => (
6             is => 'ro',
7             lazy => 1,
8             builder => '_build_seconds',
9             );
10              
11             my ($self) = @_;
12             my $seconds = $self->expression;
13 32     32   424  
14 32         82 return $seconds
15             if $seconds =~ /^\d+$/;
16 32 50       108  
17             return $self->_parse_duration($seconds)
18             }
19 32         83  
20             has epoch => (
21             is => 'ro',
22             lazy => 1,
23             builder => '_build_epoch',
24             );
25              
26             my ($self) = @_;
27             return $self->seconds if $self->seconds !~ /^[\-\+]?\d+$/;
28             $self->seconds + time;
29 31     31   257 }
30 31 100       388  
31 25         383 has gmt_string => (
32             is => 'ro',
33             builder => '_build_gmt_string',
34             lazy => 1,
35             );
36              
37             my ($self) = @_;
38             my $epoch = $self->epoch;
39             return $epoch if $epoch !~ /^\d+$/;
40              
41 60     60   6866 my ( $sec, $min, $hour, $mday, $mon, $year, $wday ) = gmtime($epoch);
42 60         778 my @months = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec);
43 60 100       648 my @days = qw(Sun Mon Tue Wed Thu Fri Sat);
44              
45 54         772 return sprintf "%s, %02d-%s-%d %02d:%02d:%02d GMT",
46 54         327 $days[$wday],
47 54         160 $mday,
48             $months[$mon],
49 54         1144 ( $year + 1900 ),
50             $hour, $min, $sec;
51             }
52              
53             has expression => (
54             is => 'ro',
55             required => 1,
56             );
57              
58             my ($class, %args) = @_;
59              
60             $args{epoch} = $args{expression}
61             if $args{expression} =~ /^\d+$/;
62              
63 79     79 0 30370 return \%args;
64             }
65              
66 79 100       422 # private
67              
68 79         1090 # This map is taken from Cache and Cache::Cache
69             # map of expiration formats to their respective time in seconds
70             #<<< no perl tidy
71             my %Units = ( map(($_, 1), qw(s second seconds sec secs)),
72             map(($_, 60), qw(m minute minutes min mins)),
73             map(($_, 60*60), qw(h hr hour hours)),
74             map(($_, 60*60*24), qw(d day days)),
75             map(($_, 60*60*24*7), qw(w week weeks)),
76             map(($_, 60*60*24*30), qw(M month months)),
77             map(($_, 60*60*24*365), qw(y year years)) );
78             #>>>
79              
80             # This code is taken from Time::Duration::Parse, except if it isn't
81             # understood it just passes it through and it adds the current time.
82             my ( $self, $timespec ) = @_;
83             my $orig_timespec = $timespec;
84              
85             # Treat a plain number as a number of seconds (and parse it later)
86             if ( $timespec =~ /^\s*([-+]?\d+(?:[.,]\d+)?)\s*$/ ) {
87             $timespec = "$1s";
88 32     32   59 }
89 32         45  
90             # Convert hh:mm(:ss)? to something we understand
91             $timespec =~ s/\b(\d+):(\d\d):(\d\d)\b/$1h $2m $3s/g;
92 32 100       128 $timespec =~ s/\b(\d+):(\d\d)\b/$1h $2m/g;
93 2         8  
94             my $duration = 0;
95             while ( $timespec
96             =~ s/^\s*([-+]?\d+(?:[.,]\d+)?)\s*([a-zA-Z]+)(?:\s*(?:,|and)\s*)*//i )
97 32         53 {
98 32         47 my ( $amount, $unit ) = ( $1, $2 );
99             $unit = lc($unit) unless length($unit) == 1;
100 32         47  
101 32         152 if ( my $value = $Units{$unit} ) {
102             $amount =~ s/,/./;
103             $duration += $amount * $value;
104 37         107 }
105 37 100       96 else {
106             return $orig_timespec;
107 37 100       97 }
108 34         54 }
109 34         111  
110             if ( $timespec =~ /\S/ ) {
111             return $orig_timespec;
112 3         39 }
113              
114             return sprintf "%.0f", $duration;
115             }
116 29 100       55  
117 3         41 1;
118              
119              
120 26         176 =pod
121              
122             =encoding UTF-8
123              
124             =head1 NAME
125              
126             Dancer2::Core::Time - class to handle common helpers for time manipulations
127              
128             =head1 VERSION
129              
130             version 0.400000
131              
132             =head1 SYNOPSIS
133              
134             my $time = Dancer2::Core::Time->new( expression => "1h" );
135             $time->seconds; # return 3600
136              
137             =head1 DESCRIPTION
138              
139             For consistency, whenever something needs to work with time, it
140             needs to be expressed in seconds, with a timestamp. Although it's very
141             convenient for the machine and calculations, it's not very handy for a
142             human-being, for instance in a configuration file.
143              
144             This class provides everything needed to translate any human-understandable
145             expression into a number of seconds.
146              
147             =head1 ATTRIBUTES
148              
149             =head2 seconds
150              
151             Number of seconds represented by the object. Defaults to 0.
152              
153             =head2 epoch
154              
155             The current epoch to handle. Defaults to seconds + time.
156              
157             =head2 gmt_string
158              
159             Convert the current value in epoch as a GMT string.
160              
161             =head2 expression
162              
163             Required. A human readable expression representing the number of seconds to provide.
164              
165             The format supported is a number followed by an expression. It currently
166             understands:
167              
168             s second seconds sec secs
169             m minute minutes min mins
170             h hr hour hours
171             d day days
172             w week weeks
173             M month months
174             y year years
175              
176             Months and years are currently fixed at 30 and 365 days. This may change.
177             Anything else is used verbatim as the expression of a number of seconds.
178              
179             Example:
180              
181             2 hours, 3 days, 3d, 1 week, 3600, etc...
182              
183             =head1 AUTHOR
184              
185             Dancer Core Developers
186              
187             =head1 COPYRIGHT AND LICENSE
188              
189             This software is copyright (c) 2022 by Alexis Sukrieh.
190              
191             This is free software; you can redistribute it and/or modify it under
192             the same terms as the Perl 5 programming language system itself.
193              
194             =cut