File Coverage

lib/Mojolicious/Plugin/Vparam/Datetime.pm
Criterion Covered Total %
statement 59 59 100.0
branch 46 52 88.4
condition 7 12 58.3
subroutine 16 16 100.0
pod 0 5 0.0
total 128 144 88.8


line stmt bran cond sub pod time code
1             package Mojolicious::Plugin::Vparam::Datetime;
2 72     72   1530425 use Mojo::Base -strict;
  72         13723  
  72         580  
3 72     72   7873 use Mojolicious::Plugin::Vparam::Common;
  72         171  
  72         78590  
4              
5             sub check_date($) {
6 9 100   9 0 40 return 'Value is not defined' unless defined $_[0];
7 8 50       40 return 'Value is not set' unless length $_[0];
8 8         417 return 0;
9             }
10              
11             sub check_time($) {
12 8 100   8 0 22 return 'Value is not defined' unless defined $_[0];
13 7 50       25 return 'Value is not set' unless length $_[0];
14 7         238 return 0;
15             }
16              
17             sub check_datetime($) {
18 36 100   36 0 117 return 'Value is not defined' unless defined $_[0];
19 31 50       106 return 'Value is not set' unless length $_[0];
20 31         1125 return 0;
21             }
22              
23             # Get a string and return DateTime or undef.
24             # Have a hack for parse Russian data and time.
25             sub parse_date($;$) {
26 53     53 0 133 my ($str, $tz) = @_;
27              
28 53 100       141 return undef unless defined $str;
29 50         189 s{^\s+}{}, s{\s+$}{} for $str;
30 50 100       176 return undef unless length $str;
31              
32 47         83 my $dt;
33              
34 47 100       244 if( $str =~ m{^\d+$} ) {
    100          
35 1         9 $dt = DateTime->from_epoch( epoch => int $str, time_zone => 'local' );
36             } elsif( $str =~ m{^[+-]} ) {
37 18         121 my @relative = $str =~ m{
38             ^([+-]) # sign
39             \s*
40             (?:(\d+)\s+)? # days
41             (?:(\d+):)?? # hours
42             (\d+) # minutes
43             (?::(\d+))? # seconds
44             $}x;
45 18         72 $dt = DateTime->now(time_zone => 'local');
46 18 100       16266 my $sub = $relative[0] eq '+' ? 'add' : 'subtract';
47 18 100       60 $dt->$sub(days => int $relative[1]) if defined $relative[1];
48 18 100       1647 $dt->$sub(hours => int $relative[2]) if defined $relative[2];
49 18 50       3002 $dt->$sub(minutes => int $relative[3]) if defined $relative[3];
50 18 100       12158 $dt->$sub(seconds => int $relative[4]) if defined $relative[4];
51             } else {
52             # RU format
53 28 100       226 if( $str =~ s{^(\d{1,2})\.(\d{1,2})\.(\d{1,4})(.*)$}{$3-$2-$1$4} ) {
54 12         73 my $cur_year = DateTime->now(time_zone => 'local')->strftime('%Y');
55 12         17618 my $cur_len = length( $cur_year ) - 1;
56             # Less digit year
57 12 100       162 if( my ($year) = $str =~ m{^(\d{1,$cur_len})-} ) {
58 1         6 $str = substr($cur_year, 0, 4 - length($year)) . $str;
59             }
60             }
61             # If looks like time add it
62 28 100       122 $str = DateTime->now(time_zone => 'local')->strftime('%F ') . $str
63             if $str =~ m{^\d{2}:};
64              
65 28         4660 $dt = eval { DateTime::Format::DateParse->parse_datetime( $str ); };
  28         190  
66 28 100       26110 return undef if $@;
67             }
68              
69 46 50       10240 return undef unless $dt;
70              
71             # Always local timezone
72 46   33     605 $tz //= DateTime->now(time_zone => 'local')->strftime('%z');
73 46         54310 $dt->set_time_zone( $tz );
74              
75 46         15458 return $dt;
76             }
77              
78             sub register {
79 74     74 0 272 my ($class, $self, $app, $conf) = @_;
80              
81             $app->vtype(
82             date =>
83             load => ['DateTime', 'DateTime::Format::DateParse'],
84 9     9   44 pre => sub { parse_date trim $_[1] },
85 9     9   38 valid => sub { check_date $_[1] },
86             post => sub {
87 9 100   9   38 return unless defined $_[1];
88             return ref($_[1]) && ( $conf->{date} || ! $_[2]->{blessed} )
89             ? $_[1]->strftime( $conf->{date} )
90 8 100 66     93 : $_[1];
91             },
92 74         1018 );
93              
94             $app->vtype(
95             time =>
96             load => ['DateTime', 'DateTime::Format::DateParse'],
97 8     8   23 pre => sub { parse_date trim $_[1] },
98 8     8   25 valid => sub { check_time $_[1] },
99             post => sub {
100 8 100   8   20 return unless defined $_[1];
101             return ref($_[1]) && ( $conf->{time} || ! $_[2]->{blessed} )
102             ? $_[1]->strftime( $conf->{time} )
103 7 50 33     57 : $_[1];
104             },
105 74         1219 );
106              
107             $app->vtype(
108             datetime =>
109             load => ['DateTime', 'DateTime::Format::DateParse'],
110 36     36   113 pre => sub { parse_date trim $_[1] },
111 36     36   104 valid => sub { check_datetime $_[1] },
112             post => sub {
113 36 100   36   99 return unless defined $_[1];
114             return ref($_[1]) && ( $conf->{datetime} || ! $_[2]->{blessed} )
115             ? $_[1]->strftime( $conf->{datetime} )
116 33 100 100     258 : $_[1];
117             },
118 74         889 );
119              
120              
121 74         370 return;
122             }
123              
124             1;