#!/usr/bin/env perl
use strict;
use warnings;
use Test::More;
use DateTime;
use DateTime::SpanSet;
# Check that SpanSets return spans with the correct endpoints during daylight
# savings changeovers given a weekly recurrence.
BEGIN {
if (eval 'use DateTime::Event::Recurrence; 1') {
plan tests => 552;
}
else {
plan skip_all => 'DateTime::Event::Recurrence required for this test.';
}
}
test_span_set_on_day(4, 'Thursday', 27, 3);
test_span_set_on_day(5, 'Friday', 28, 3);
test_span_set_on_day(6, 'Saturday', 29, 3);
test_span_set_on_day(6, 'Saturday', 4, 10);
test_span_set_on_day(7, 'Sunday', 5, 10);
test_span_set_on_day(1, 'Monday', 6, 10);
sub test_span_set_on_day {
my ($day_index, $day_name, $day_of_month, $month) = @_;
my $span_set =
DateTime::SpanSet
->from_sets(
start_set =>
DateTime::Event::Recurrence->weekly(
days => $day_index, hours => 8, minutes => 30,
),
end_set =>
DateTime::Event::Recurrence->weekly(
days => $day_index, hours => 15, minutes => 30,
),
)
->set_time_zone('Asia/Jerusalem');
my $expected_date = new_as_of_time($month, $day_of_month, 0);
my $expected_start =
$expected_date->clone()->add(days => -7)->set_hour(8)->set_minute(30);
my $expected_end =
$expected_date->clone()->add(days => -7)->set_hour(15)->set_minute(30);
# Skip 2am due to daylight savings change.
foreach my $hour (0..1, 3..8) {
my $as_of_time = new_as_of_time($month, $day_of_month, $hour);
my $span = $span_set->current($as_of_time)->span();
test_span_end_point(
'start', $span->start(), $expected_start, $as_of_time,
);
test_span_end_point(
'end', $span->end(), $expected_end, $as_of_time,
);
}
$expected_start = $expected_date->clone()->set_hour(8)->set_minute(30);
$expected_end = $expected_date->clone()->set_hour(15)->set_minute(30);
foreach my $hour (9..23) {
my $as_of_time = new_as_of_time($month, $day_of_month, $hour);
my $span = $span_set->current($as_of_time)->span();
test_span_end_point(
'start', $span->start(), $expected_start, $as_of_time,
);
test_span_end_point(
'end', $span->end(), $expected_end, $as_of_time,
);
}
return;
}
sub new_as_of_time {
my ($month, $day_of_month, $hour) = @_;
return
DateTime->new(
year => 2008,
month => $month,
day => $day_of_month,
hour => $hour,
time_zone => 'Asia/Jerusalem'
);
}
sub test_span_end_point {
my ($end_point_name, $end_point, $expected_time, $test_input_time) = @_;
my $expected_ymd = $expected_time->ymd();
my $expected_hms = $expected_time->hms();
my $test_input_string =
$test_input_time->ymd() . q< > . $test_input_time->hms();
is(
$end_point->ymd(),
$expected_ymd,
"Date for $end_point_name of span at $test_input_string.",
);
is(
$end_point->hms(),
$expected_hms,
"Time of day for $end_point_name of span at $test_input_string.",
);
return;
}