#!/usr/bin/perl use strict; use warnings; use feature qw( :5.10 ); use DateTime; use DateTime::Duration; use DateTime::Set; use DateTime::Span;
my $starting_date = { day => 5, hour => 0, minute => 0, second => 0 }; my $range_ref = { days => 5, hours => 20, minutes => 0, seconds => 0 }; my ($dt, $rv); # Example 1: Date being tested is explicitly set $dt = DateTime->new( year => 2009, month => 12, day => 31, hour => 12, minute => 36, second => 47, ); $rv = validate( { starting_date => $starting_date, range => $range_ref, target => $dt, } ); $rv ? say "$dt is in range" : say "$dt is not in range"; # Example 2: Date being tested is explicitly set $dt = DateTime->new( year => 2010, month => 1, day => 1, hour => 12, minute => 36, second => 47, ); $rv = validate( { starting_date => $starting_date, range => $range_ref, target => $dt, } ); $rv ? say "$dt is in range" : say "$dt is not in range"; # Example 3: Test 'now' $dt = DateTime->now(); $rv = validate( { starting_date => $starting_date, range => $range_ref, target => $dt, } ); $rv ? say "$dt is in range" : say "$dt is not in range"; ##### SUBROUTINES ##### sub validate { my $args = shift; my $sixdays = DateTime::Duration->new( days => 6 ); my $oneweek = DateTime::Duration->new( weeks => 1 ); my $dt1 = $args->{target}->clone(); $dt1->set( hour => $args->{starting_date}->{hour}, minute => $args->{starting_date}->{minute}, second => $args->{starting_date}->{second}, ); my $starting_date_minus_6 = $dt1 - $sixdays; my $spanweek = DateTime::Span->from_datetime_and_duration( start => $starting_date_minus_6, duration => $oneweek ); my $set = DateTime::Set->from_recurrence( recurrence => sub { return $_[0] if $_[0]->is_infinite; return $_[0]->add( days => 1 ) }, span => $spanweek, ); my $start_of_span = _get_start_of_span( $args->{starting_date}, $set ); my $allowable_range = DateTime::Duration->new( %{ $args->{range} } ); my $span_allow = DateTime::Span->from_datetime_and_duration( start => $start_of_span, duration => $allowable_range ); _date_is_in_span( $args->{target}, $span_allow ); } sub _get_start_of_span { my ($starting_date, $set) = @_; my $iter = $set->iterator; my $starting_dt; while ( my $x = $iter->next ) { if ( $x->dow eq $starting_date->{day} ) { $starting_dt = $x->clone(); last; } }; return $starting_dt; } sub _date_is_in_span { my ( $date, $span ) = @_; $span->contains( $date ) ? 1 : 0; }
The attached file, zinspan.pl, is my first attempt at using DateTime to solve a practical problem. I am looking for feedback both on the program's validity and on whether there is the making of a new DateTime module in it.
Problem: Suppose that a 'week' can begin at an arbitrarily chosen day of the week and time of day. Suppose further that that week can be divided into two subspans: one in which an event is permitted to occur, and the other in which the event is not permitted to occur. Write a function that returns true if the event's date is in the permitted subspan and false if it is in the forbidden subspan.
Example: A file is to be processed if it arrives on the system anytime between Friday midnight and Wednesday 8:00 pm. The file has arrived. Is it okay to process it?
Thank you very much. Jim Keenan