Skip to content

Commit

Permalink
Change DateRange methods to attributes.
Browse files Browse the repository at this point in the history
This means they will only be calculated once, and e.g. calling code
doesn't have to worry about caching them. Include documentation.
  • Loading branch information
dracos committed Nov 28, 2023
1 parent 57c8a7b commit ab7035a
Showing 1 changed file with 87 additions and 26 deletions.
113 changes: 87 additions & 26 deletions perllib/FixMyStreet/DateRange.pm
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
=head1 NAME
FixMyStreet::DateRange - little wrapper of an inclusive date range
=head1 SYNOPSIS
Given a start/end date, this can be used to return DBIx::Class parameters for
searching within that date range, inclusive of both start and end dates.
=head1 DESCRIPTION
=cut

package FixMyStreet::DateRange;

use DateTime;
Expand All @@ -7,23 +20,38 @@ use Try::Tiny;

my $one_day = DateTime::Duration->new( days => 1 );

=over 4
=item * start_date and end_date - provided start and end dates, to be parsed
=cut

has start_date => ( is => 'ro' );

=item * start_default - default to use if start_date not provided
=cut

has start_default => ( is => 'ro' );

has end_date => ( is => 'ro' );

=item * parser - defaults to DateTime::Format::Flexible
=cut

has parser => (
is => 'ro',
default => sub { DateTime::Format::Flexible->new }
);

=item * formatter - defaults to same as parser
=cut

has formatter => (
is => 'lazy',
default => sub {
my $self = shift;
return $self->parser;
}
default => sub { $_[0]->parser }
);

sub _dt {
Expand All @@ -36,37 +64,70 @@ sub _dt {
return $d;
}

sub start {
my $self = shift;
$self->_dt($self->start_date) || $self->start_default
}
=back
sub end {
my $self = shift;
my $d = $self->_dt($self->end_date);
$d += $one_day if $d;
return $d;
}
=head2 METHODS
=over 4
=item * start / end - provides DateTimes of the start/end of the range
=cut

has start => (
is => 'lazy',
default => sub {
$_[0]->_dt($_[0]->start_date) || $_[0]->start_default
}
);

has end => (
is => 'lazy',
default => sub {
my $d = $_[0]->_dt($_[0]->end_date);
$d += $one_day if $d;
return $d;
}
);

sub _formatted {
my ($self, $dt) = @_;
return unless $dt;
$self->formatter->format_datetime($dt);
}

sub start_formatted { $_[0]->_formatted($_[0]->start) }
sub end_formatted { $_[0]->_formatted($_[0]->end) }
=item * start_formatted / end_formatted - formatted timestamps
sub sql {
my ($self, $default) = @_;
my $sql = {};
if (my $start = $self->start_formatted) {
$sql->{'>='} = $start;
}
if (my $end = $self->end_formatted) {
$sql->{'<'} = $end;
=cut

has start_formatted => (
is => 'lazy',
default => sub { $_[0]->_formatted($_[0]->start) }
);

has end_formatted => (
is => 'lazy',
default => sub { $_[0]->_formatted($_[0]->end) }
);

=item * sql - returns a hashref of two comparison operators for the range
=back
=cut

has sql => (
is => 'lazy',
default => sub {
my $sql = {};
if (my $start = $_[0]->start_formatted) {
$sql->{'>='} = $start;
}
if (my $end = $_[0]->end_formatted) {
$sql->{'<'} = $end;
}
return $sql;
}
return $sql;
}
);

1;

0 comments on commit ab7035a

Please sign in to comment.