1 package Reaction::UI::ViewPort::Field::TimeRange;
4 use Reaction::Types::DateTime;
7 use Time::ParseDate ();
9 class TimeRange is 'Reaction::UI::ViewPort::InterfaceModel::Field', which {
11 has '+value' => (isa => 'DateTime::SpanSet');
13 #has '+layout' => (default => 'timerange');
16 (isa => 'Str', is => 'rw', lazy_fail => 1, trigger_adopt('value_string'));
19 isa => 'Str', is => 'rw', required => 1, default => sub { 'Delete' },
23 isa => 'Reaction::UI::ViewPort::TimeRangeCollection',
29 implements _build_value_string => as {
31 #return '' unless $self->has_value;
32 #return $self->value_string;
35 implements value_array => as {
37 return split(',', $self->value_string);
40 implements adopt_value_string => as {
42 my @values = $self->value_array;
43 for my $idx (0 .. 3) { # last value is repeat
44 if (length $values[$idx]) {
45 my ($epoch) = Time::ParseDate::parsedate($values[$idx], UK => 1);
46 $values[$idx] = DateTime->from_epoch( epoch => $epoch );
49 $self->value($self->range_to_spanset(@values));
52 implements range_to_spanset => as {
53 my ($self, $time_from, $time_to, $repeat_from, $repeat_to, $pattern) = @_;
54 my $spanset = DateTime::SpanSet->empty_set;
55 if (!$pattern || $pattern eq 'none') {
56 my $span = DateTime::Span->from_datetimes(
57 start => $time_from, end => $time_to
59 $spanset = $spanset->union( $span );
61 my $duration = $time_to - $time_from;
62 my %args = ( days => $time_from->day + 2,
63 hours => $time_from->hour,
64 minutes => $time_from->minute,
65 seconds => $time_from->second );
67 delete $args{'days'} if ($pattern eq 'daily');
68 delete @args{qw/hours days/} if ($pattern eq 'hourly');
69 $args{'days'} = $time_from->day if ($pattern eq 'monthly');
70 my $start_set = DateTime::Event::Recurrence->$pattern( %args );
71 my $iter = $start_set->iterator( start => $repeat_from, end => $repeat_to );
72 while ( my $dt = $iter->next ) {
73 my $endtime = $dt + $duration;
74 my $new_span = DateTime::Span->from_datetimes(
78 $spanset = $spanset->union( $new_span );
84 implements delete => as {
86 $self->parent->remove_range_vp($self);
89 override accept_events => sub { ('value_string', 'delete', super()) };
97 Reaction::UI::ViewPort::Field::TimeRange
107 Accessor for a L<DateTime::SpanSet> object.
111 Returns: Encoded range string representing the value.
115 Returns: Arrayref of the elements of C<value_string>.
119 L<Reaction::UI::ViewPort::TimeRangeCollection> object.
121 =head2 range_to_spanset
123 Arguments: $self, $time_from, $time_to, $repeat_from, $repeat_to, $pattern
124 where $time_from, $time_to, $repeat_from, $repeat_to are L<DateTime>
125 objects, and $pattern is a L<DateTime::Event::Recurrence> method name
131 Removes TimeRange from C<parent> collection.
135 Label for the delete option. Default: 'Delete'.
139 =head2 L<Reaction::UI::ViewPort::Field>
141 =head2 L<Reaction::UI::ViewPort::TimeRangeCollection>
145 See L<Reaction::Class> for authors.
149 See L<Reaction::Class> for the license.