http://qs321.pair.com?node_id=1033261


in reply to Re: Determine if a given DateTime is a member of a DateTime::Set
in thread Determine if a given DateTime is a member of a DateTime::Set

the "in-between" weeks properly fail.

No, the second call to Test::More::is:

is($biweekly->contains($date), 0, $date->ymd . ' is *NOT* the bi-weekl +y set');

succeeds only if the call to contains returns 0, i.e., if the DateTime::Set object $biweekly does not contain the specified date (which it shouldn’t). But the call to contains is actually (and incorrectly) returning 1, thereby indicating that the object does contain the given date. So, the test fails because the call to contains returns the wrong answer in this case.

To the OP: I’ve been playing with the code, but haven’t found any way of making it work correctly. So, either the module is buggy, or, at the least, it is poorly documented.

I did notice that you are calling the contains method with a scalar, whereas the module documentation says it takes a list. But putting the argument into an array and passing that to the function makes no difference to the result of the tests. :-(

Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

Replies are listed 'Best First'.
Re^3: Determine if a given DateTime is a member of a DateTime::Set
by farang (Chaplain) on May 13, 2013 at 09:21 UTC

    I agree, the documentation for that module is murky and confusing. I also played around with it for a while without success. DateTime::Event::ICal has a cleaner API for creating the DateTime::Set object. This replacement makes it work, leaving the rest of the original code alone.

    use DateTime::Event::ICal; my $biweekly = DateTime::Event::ICal->recur( dtstart => DateTime->today(), freq => 'weekly', interval => 2, );

Re^3: Determine if a given DateTime is a member of a DateTime::Set
by jakeease (Friar) on May 13, 2013 at 08:59 UTC

    Thanks; I did read that too fleetingly.

Re^3: Determine if a given DateTime is a member of a DateTime::Set
by vagabonding electron (Curate) on May 14, 2013 at 16:07 UTC

    I dare come again out of the wood...

    It seems that it is important that a DateTime::Set has both start and end point.

    Here is my today's attempt with and without an end point and the output below is different (correct if end point is defined):

    #!/usr/bin/perl use strict; use warnings; use DateTime; use DateTime::Set; my $start = DateTime->today(); my $end = DateTime->today()->add('days' => 90); my $biweekly = DateTime::Set->from_recurrence( 'recurrence' => sub { return $_[0]->add('days' => 14)->truncate('to' => 'day') }, 'start' => $start, 'end' => $end, # !!! This is critical. ); my $iter = $biweekly->iterator; print "This is the set with defined 'end': ", $/; while ( my $dt = $iter->next ) { print $dt->datetime, $/; }; print $/; print 'TESTING whether Date is in set...', $/; my $date = DateTime->today(); print $biweekly->contains($date), ' ', $date->ymd, $/; $date->add('days' => 7); print $biweekly->contains($date), ' ', $date->ymd, $/; $date->add('days' => 7); print $biweekly->contains($date), ' ', $date->ymd, $/; $date->add('days' => 7); print $biweekly->contains($date), ' ', $date->ymd, $/; $date->add('days' => 7); print $biweekly->contains($date), ' ', $date->ymd, $/; $date->add('days' => 7); print $biweekly->contains($date), ' ', $date->ymd, $/; print $/; print "This is the begin of the set with 'end' commented out: ", $/; $biweekly = DateTime::Set->from_recurrence( 'recurrence' => sub { return $_[0]->add('days' => 14)->truncate('to' => 'day') }, 'start' => $start, # 'end' => $end, # !!! This is critical. ); $iter = $biweekly->iterator; while ( my $dt = $iter->next ) { last if $dt > $end; # to avoid the infinite loop. print $dt->datetime, $/; }; print $/; print 'TESTING whether Date is in set...', $/; $date = DateTime->today(); print $biweekly->contains($date), ' ', $date->ymd, $/; $date->add('days' => 7); print $biweekly->contains($date), ' ', $date->ymd, $/; $date->add('days' => 7); print $biweekly->contains($date), ' ', $date->ymd, $/; $date->add('days' => 7); print $biweekly->contains($date), ' ', $date->ymd, $/; $date->add('days' => 7); print $biweekly->contains($date), ' ', $date->ymd, $/; $date->add('days' => 7); print $biweekly->contains($date), ' ', $date->ymd, $/;

    The output:

    C:\Perl\bin>perl N:\Perle\Learn\DateTime\pm_1033231_orig_analyse_003_h +.pl This is the set with defined 'end': 2013-05-14T00:00:00 2013-05-28T00:00:00 2013-06-11T00:00:00 2013-06-25T00:00:00 2013-07-09T00:00:00 2013-07-23T00:00:00 2013-08-06T00:00:00 TESTING whether Date is in set... 1 2013-05-14 0 2013-05-21 1 2013-05-28 0 2013-06-04 1 2013-06-11 0 2013-06-18 This is the begin of the set with 'end' commented out: 2013-05-14T00:00:00 2013-05-28T00:00:00 2013-06-11T00:00:00 2013-06-25T00:00:00 2013-07-09T00:00:00 2013-07-23T00:00:00 2013-08-06T00:00:00 TESTING whether Date is in set... 1 2013-05-14 1 2013-05-21 1 2013-05-28 1 2013-06-04 1 2013-06-11 1 2013-06-18

      Bravo! and ++vagabonding electron (when Vote Fairy next visits) for persevering and finding a way to make this work.

      But, for the record, this is what the DateTime::Set documentation says:

      The second type of set that it can handle is one based on a recurrence.... This type of set can have fixed starting and ending datetimes, but neither is required.

      (Emphasis added.) So, at the very least we’ll have to say that this module is not working as advertised. :-(

      Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

        Thank you Athanasius I was very pleased to hear that (I mean the first word :-) ).