File Coverage

blib/lib/Mojar/Cron/Date.pm
Criterion Covered Total %
statement 37 64 57.8
branch 7 28 25.0
condition 6 20 30.0
subroutine 12 27 44.4
pod 15 19 78.9
total 77 158 48.7


line stmt bran cond sub pod time code
1             package Mojar::Cron::Date;
2 1     1   219101 use Mojo::Base -strict;
  1         8  
  1         6  
3              
4             our $VERSION = 0.021;
5              
6 1     1   139 use Carp qw(croak);
  1         1  
  1         39  
7 1     1   440 use POSIX qw(strftime);
  1         5281  
  1         4  
8 1     1   1160 use Scalar::Util qw(blessed);
  1         1  
  1         136  
9              
10             use overload
11 60     60   111 '""' => sub { ${$_[0]} },
  60         82  
12 0 0   0   0 '<=>' => sub { (${$_[0]} cmp $_[1]) * ($_[2] ? -1 : 1) },
  0         0  
13 1     1   6 fallback => 1;
  1         2  
  1         8  
14              
15             sub new {
16 29     29 0 15738 my $proto = shift;
17 29   33     84 my $class = ref $proto || $proto;
18 29 0       52 my $payload = @_ ? shift : ref $proto ? $$proto : $class->today;
    50          
19 29         76 bless \$payload => $class;
20             }
21              
22             sub today {
23 0     0 1 0 my ($d, $m , $y) = (localtime)[3, 4, 5];
24 0         0 return shift->new(sprintf '%04u-%02u-%02u', $y + 1900, $m + 1, $d);
25             }
26              
27             sub current {
28 0     0 1 0 my ($d, $m , $y) = (gmtime)[3, 4, 5];
29 0         0 return shift->new(sprintf '%04u-%02u-%02u', $y + 1900, $m + 1, $d);
30             }
31              
32             sub roll {
33 0     0 1 0 my ($self, $days) = @_;
34 0 0       0 croak 'Not a class method' unless ref $self;
35 0 0       0 croak "Bad date format ($$self)" unless $$self =~ /^(\d{4})-(\d\d)-(\d\d)\b/a;
36 0   0     0 $$self = strftime '%Y-%m-%d', 0, 0, 12, $3 + ($days // 0), $2 - 1, $1 - 1900;
37 0         0 return $self;
38             }
39              
40 0   0 0 1 0 sub roll_back { shift->roll(-(shift // 0)) }
41              
42 0     0 1 0 sub after { shift->new->roll(shift) }
43              
44 0   0 0 1 0 sub before { shift->new->roll(-(shift // 0)) }
45              
46 0     0 1 0 sub next { shift->new->roll(1) }
47              
48 0     0 1 0 sub previous { shift->new->roll(-1) }
49              
50 0     0 1 0 sub tomorrow { shift->today->roll(1) }
51              
52 0     0 1 0 sub yesterday { shift->today->roll(-1) }
53              
54             sub format {
55 27     27 1 61 my ($self, $format, $date) = @_;
56 27 50 33     101 $date ||= ref $self ? $$self : croak 'Missing required date';
57 27 50       110 croak "Bad date format ($date)" unless $date =~ /^(\d{4})-(\d\d)-(\d\d)\b/a;
58 27 50       69 die "Unsupported platform ($^O)" unless $^O eq 'linux';
59 27   50     800 strftime($format || '%Y-%m-%d', 0, 0, 0, $3, $2 - 1, $1 - 1900);
60             }
61              
62 9     9 1 25 sub dow { shift->format('%u', @_) }
63              
64 0     0 0 0 sub yearweek { shift->format('%G%V', @_) }
65              
66 0     0 0 0 sub yearweekday { shift->format('%GW%V%u', @_) }
67              
68             sub is_weekend {
69 0     0 1 0 my $self = shift;
70 0         0 my $dow = $self->dow(shift);
71 0 0       0 $dow == 6 or $dow == 7;
72             }
73              
74             sub roll_to {
75 0     0 1 0 my ($self, $dow) = @_;
76 0 0       0 croak 'Missing required day-of-the-week' unless defined $dow;
77 0         0 my $day = $self->dow;
78 0         0 $self->roll(($dow - $day) % 7);
79             }
80              
81             sub epoch_days {
82 11     11 0 13 my ($self) = @_;
83 11 50       57 croak "Bad date format ($$self)" unless $$self =~ /^(\d{4})-(\d\d)-(\d\d)\b/a;
84 11 50       30 die "Unsupported platform ($^O)" unless $^O eq 'linux';
85 11         50 return _epoch_days($1, $2, $3);
86             }
87              
88             sub sleeps {
89 1     1 1 5 my ($self, $other) = @_;
90 1 0 33     14 (blessed $other and $other->isa('Mojar::Cron::Date'))
    50          
91             ? $other->epoch_days - $self->epoch_days
92             : ref $other
93             ? croak sprintf('Invalid type (%s)', ref $other)
94             : $other - $self->epoch_days;
95             }
96              
97             # Determine base value for epoch
98             my $Epoch = 0; # starting point, affects base value
99             $Epoch = _epoch_days(1970, 1, 1); # set base value
100             my %Cache = (); # reset cache after above calculation
101              
102             sub _epoch_days {
103             # Args: ($year, $1-based-month, $day-of-month)
104             # Borrowed from Time::Local...
105             # Only expected to be correct on linux
106 12   66 12   78 $_[2] + ($Cache{pack ss => @_[0, 1]} ||= do {
107 10         27 my $month = ($_[1] + 9) % 12;
108 10         23 my $year = $_[0] - int($month / 10);
109              
110 10         56 365 * $year
111             + int($year / 4) - int($year / 100) + int($year / 400)
112             + int(($month * 306 + 5) / 10)
113             - $Epoch;
114             })
115             }
116              
117             1;
118             __END__