FAQ
To whom it may concern,

I have what I think is a simple couple methods for estimating delivery
dates (We are a custom printing shop and build in padding to allow for
acquire and printing then give the customer an estimate on how many days we
can complete and ship):

sub calculateOrderDeliveryDate
{
     my ($self, $orderDate, $serviceDays) = @_;

     warn Dumper("$orderDate --- $serviceDays");

     my @workingDays = $self->_getWorkingDays($orderDate, max (25,
$serviceDays)); # Optimize search to 25 days out...

     return $workingDays[$serviceDays];
}

sub _getWorkingDays
{
     my ($self, $startDate, $count) = @_;
     my $startDay = DateTime->from_object( object => $startDate )->truncate(
to => 'day' );
     my $iterator = DateTime::Event::Recurrence->weekly( days => [1..5]
)->iterator(
         after => DateTime->from_object( object => $startDay ),
     );

     my @result = ();

     while ($count > scalar @result)
     {
         my $date = $iterator->next;
         warn Dumper("$date -> ");
         if ($date && !isHoliday($date)) {
             push @result, $date;
         }
     }

     return \@result;
}

Which when called using (Local and server):

perl -e "use DateTime; use Util::Dates;
Util::Dates->calculateOrderDeliveryDate(DateTime->now(), 7);"

Logs out:

$VAR1 = '2016-02-10T17:51:31 --- 7';
$VAR1 = '2016-02-12T00:00:00 -> ';
$VAR1 = '2016-02-15T00:00:00 -> ';
$VAR1 = '2016-02-16T00:00:00 -> ';
$VAR1 = '2016-02-17T00:00:00 -> ';
$VAR1 = '2016-02-18T00:00:00 -> ';
$VAR1 = '2016-02-19T00:00:00 -> ';
$VAR1 = '2016-02-22T00:00:00 -> ';
$VAR1 = '2016-02-23T00:00:00 -> ';
$VAR1 = '2016-02-24T00:00:00 -> ';
$VAR1 = '2016-02-25T00:00:00 -> ';
$VAR1 = '2016-02-26T00:00:00 -> ';
$VAR1 = '2016-02-29T00:00:00 -> ';
$VAR1 = '2016-03-01T00:00:00 -> ';
$VAR1 = '2016-03-02T00:00:00 -> ';
$VAR1 = '2016-03-03T00:00:00 -> ';
$VAR1 = '2016-03-04T00:00:00 -> ';
$VAR1 = '2016-03-07T00:00:00 -> ';
$VAR1 = '2016-03-08T00:00:00 -> ';
$VAR1 = '2016-03-09T00:00:00 -> ';
$VAR1 = '2016-03-10T00:00:00 -> ';
$VAR1 = '2016-03-11T00:00:00 -> ';
$VAR1 = '2016-03-14T00:00:00 -> ';
$VAR1 = '2016-03-15T00:00:00 -> ';
$VAR1 = '2016-03-16T00:00:00 -> ';
$VAR1 = '2016-03-17T00:00:00 -> ';

Which is what I want.

When running the same code under an Apache web request on the server, the
Apache error log file contains:

[Wed Feb 10 12:49:32 2016] main.cgi: $VAR1 = '2016-02-10T12:49:32 --- 7';
[Wed Feb 10 12:49:32 2016] main.cgi: $VAR1 = '2016-02-11T00:00:00 -> ';
[Wed Feb 10 12:49:32 2016] main.cgi: $VAR1 = '2016-02-15T00:00:00 -> ';
[Wed Feb 10 12:49:32 2016] main.cgi: $VAR1 = '2016-02-19T00:00:00 -> ';
[Wed Feb 10 12:49:32 2016] main.cgi: $VAR1 = '2016-02-22T00:00:00 -> ';
[Wed Feb 10 12:49:32 2016] main.cgi: $VAR1 = '2016-02-26T00:00:00 -> ';
[Wed Feb 10 12:49:32 2016] main.cgi: $VAR1 = '2016-02-29T00:00:00 -> ';
[Wed Feb 10 12:49:32 2016] main.cgi: $VAR1 = '2016-03-04T00:00:00 -> ';
[Wed Feb 10 12:49:32 2016] main.cgi: $VAR1 = '2016-03-07T00:00:00 -> ';
[Wed Feb 10 12:49:32 2016] main.cgi: $VAR1 = '2016-03-11T00:00:00 -> ';
[Wed Feb 10 12:49:32 2016] main.cgi: $VAR1 = '2016-03-14T00:00:00 -> ';
[Wed Feb 10 12:49:32 2016] main.cgi: $VAR1 = '2016-03-18T00:00:00 -> ';
[Wed Feb 10 12:49:32 2016] main.cgi: $VAR1 = '2016-03-21T00:00:00 -> ';
[Wed Feb 10 12:49:32 2016] main.cgi: $VAR1 = '2016-03-25T00:00:00 -> ';
[Wed Feb 10 12:49:32 2016] main.cgi: $VAR1 = '2016-03-28T00:00:00 -> ';
[Wed Feb 10 12:49:32 2016] main.cgi: $VAR1 = '2016-04-01T00:00:00 -> ';
[Wed Feb 10 12:49:32 2016] main.cgi: $VAR1 = '2016-04-04T00:00:00 -> ';
[Wed Feb 10 12:49:32 2016] main.cgi: $VAR1 = '2016-04-08T00:00:00 -> ';
[Wed Feb 10 12:49:32 2016] main.cgi: $VAR1 = '2016-04-11T00:00:00 -> ';
[Wed Feb 10 12:49:32 2016] main.cgi: $VAR1 = '2016-04-15T00:00:00 -> ';
[Wed Feb 10 12:49:32 2016] main.cgi: $VAR1 = '2016-04-18T00:00:00 -> ';
[Wed Feb 10 12:49:32 2016] main.cgi: $VAR1 = '2016-04-22T00:00:00 -> ';
[Wed Feb 10 12:49:32 2016] main.cgi: $VAR1 = '2016-04-25T00:00:00 -> ';
[Wed Feb 10 12:49:32 2016] main.cgi: $VAR1 = '2016-04-29T00:00:00 -> ';
[Wed Feb 10 12:49:32 2016] main.cgi: $VAR1 = '2016-05-02T00:00:00 -> ';
[Wed Feb 10 12:49:32 2016] main.cgi: $VAR1 = '2016-05-06T00:00:00 -> ';
[Wed Feb 10 12:49:32 2016] main.cgi: $VAR1 = '2016-02-10T12:49:32 --- 21';
[Wed Feb 10 12:49:32 2016] main.cgi: $VAR1 = '2016-02-11T00:00:00 -> ';
[Wed Feb 10 12:49:32 2016] main.cgi: $VAR1 = '2016-02-13T00:00:00 -> ';
[Wed Feb 10 12:49:33 2016] main.cgi: $VAR1 = '2016-02-20T00:00:00 -> ';
[Wed Feb 10 12:49:33 2016] main.cgi: Can't call method "is_infinite" on an
undefined value at
/usr/local/share/perl/5.14.2/DateTime/Event/Recurrence.pm line 870.

The initial call is for 7 day delivery estimate followed by a 21 day
delivery estimate. Since both of these are under 21 days, they run the 25
day estimate (which I was Memoizing to save from calling it repeatedly...)
The Error I think is inconsequential to the issue I'm concerned with. If
you look at the dates logged out, it prints the Monday and Friday dates and
I can't figure out why. On the second call, it logs out Friday then tries
Sunday (which isn't in the recurrence range) followed by the next Sunday
which then eventually fails.

I've verified that the following packages are updated on the server (Ubuntu
12.04):

DateTime is up to date. (1.21)
DateTime::Event::Recurrence is up to date. (0.18)
DateTime::Format::CLDR is up to date. (1.17)
DateTime::Format::ICal is up to date. (0.09)
DateTime::Set is up to date. (0.3600)

The versions match my local copy.

Server:
Distributor ID: Ubuntu
Description: Ubuntu 12.04.5 LTS
Release: 12.04
Codename: precise

Local:
Distributor ID: Debian
Description: Debian GNU/Linux testing-updates (sid)
Release: testing-updates
Codename: sid

Perl: v5.14.2 (which I limited to match server version
since 5.22 is on Debian Testing)


Do you have any troubleshooting steps I can take to figure out why the
iterator would only be stepping over Monday and Friday and skipping the
Tues/Weds/Thur dates? (I've tried removing the range and using an array of
[1. 2. 3. 4. 5] in the Recurrence to no avail)

I had used the DateTime::Event::Holiday::US file previously to complement
the weekday set I am generating and I went through removing all that to
track down what this problem is.

Nick

Search Discussions

  • Flavio S. Glock at Feb 11, 2016 at 9:25 am
    debugging here - I've written this:

    ---
    use DateTime;
    use DateTime::Event::Recurrence;

    my $startDate = DateTime->new(
         year => 2016,
         month => 2,
         day => 10,
         hour => 17,
         minute => 51,
         second => 31,
         nanosecond => 123456,
         time_zone => 'America/Chicago',
    );
    my $count = 15;
    my $startDay = DateTime->from_object( object => $startDate
    )->truncate( to => 'day' );
    my $iterator = DateTime::Event::Recurrence->weekly( days => [ 1 .. 5 ]
    )->iterator(
         after => DateTime->from_object(
             object => $startDay
         ),
    );
    my @result = ();
    while ( $count-- ) {
         my $date = $iterator->next;
         print "$date ", $date->day_of_week(), "\n";
    }
    ---

    troubleshooting steps:

    I would try again without calling isHoliday($date) inside the loop.
    This is to rule out that $date is being modified.

    Alternately, specify a bounded recurrence (one with start and end
    dates). This is to force precalculation of the set, before the
    iterator starts. For example, using DateTime::Event::ICal:

    ---
    use DateTime;
    use DateTime::Event::ICal;

    my $startDate = DateTime->new(
         year => 2016,
         month => 2,
         day => 10,
         hour => 17,
         minute => 51,
         second => 31,
         nanosecond => 123456,
         time_zone => 'America/Chicago',
    );
    my $startDay = DateTime->from_object( object => $startDate
    )->truncate( to => 'day' )->add( days => 1 );
    my $iterator = DateTime::Event::ICal->recur(
         dtstart => $startDay,
         freq => 'weekly',
         byday => [ "mo", "tu", "we", "th", "fr" ],
         count => 15,
    )->iterator();
    my @result = ();
    while ( my $date = $iterator->next ) {
         print "$date ", $date->day_of_week(), "\n";
    }
    ---

    please let me know what you get.

    Flávio


    2016-02-10 19:19 GMT+01:00 Nicholas Schubach <nschubach@gmail.com>:
    To whom it may concern,

    I have what I think is a simple couple methods for estimating delivery dates
    (We are a custom printing shop and build in padding to allow for acquire and
    printing then give the customer an estimate on how many days we can complete
    and ship):

    sub calculateOrderDeliveryDate
    {
    my ($self, $orderDate, $serviceDays) = @_;

    warn Dumper("$orderDate --- $serviceDays");

    my @workingDays = $self->_getWorkingDays($orderDate, max (25,
    $serviceDays)); # Optimize search to 25 days out...

    return $workingDays[$serviceDays];
    }

    sub _getWorkingDays
    {
    my ($self, $startDate, $count) = @_;
    my $startDay = DateTime->from_object( object => $startDate )->truncate(
    to => 'day' );
    my $iterator = DateTime::Event::Recurrence->weekly( days => [1..5]
    )->iterator(
    after => DateTime->from_object( object => $startDay ),
    );

    my @result = ();

    while ($count > scalar @result)
    {
    my $date = $iterator->next;
    warn Dumper("$date -> ");
    if ($date && !isHoliday($date)) {
    push @result, $date;
    }
    }

    return \@result;
    }

    Which when called using (Local and server):

    perl -e "use DateTime; use Util::Dates;
    Util::Dates->calculateOrderDeliveryDate(DateTime->now(), 7);"

    Logs out:

    $VAR1 = '2016-02-10T17:51:31 --- 7';
    $VAR1 = '2016-02-12T00:00:00 -> ';
    $VAR1 = '2016-02-15T00:00:00 -> ';
    $VAR1 = '2016-02-16T00:00:00 -> ';
    $VAR1 = '2016-02-17T00:00:00 -> ';
    $VAR1 = '2016-02-18T00:00:00 -> ';
    $VAR1 = '2016-02-19T00:00:00 -> ';
    $VAR1 = '2016-02-22T00:00:00 -> ';
    $VAR1 = '2016-02-23T00:00:00 -> ';
    $VAR1 = '2016-02-24T00:00:00 -> ';
    $VAR1 = '2016-02-25T00:00:00 -> ';
    $VAR1 = '2016-02-26T00:00:00 -> ';
    $VAR1 = '2016-02-29T00:00:00 -> ';
    $VAR1 = '2016-03-01T00:00:00 -> ';
    $VAR1 = '2016-03-02T00:00:00 -> ';
    $VAR1 = '2016-03-03T00:00:00 -> ';
    $VAR1 = '2016-03-04T00:00:00 -> ';
    $VAR1 = '2016-03-07T00:00:00 -> ';
    $VAR1 = '2016-03-08T00:00:00 -> ';
    $VAR1 = '2016-03-09T00:00:00 -> ';
    $VAR1 = '2016-03-10T00:00:00 -> ';
    $VAR1 = '2016-03-11T00:00:00 -> ';
    $VAR1 = '2016-03-14T00:00:00 -> ';
    $VAR1 = '2016-03-15T00:00:00 -> ';
    $VAR1 = '2016-03-16T00:00:00 -> ';
    $VAR1 = '2016-03-17T00:00:00 -> ';

    Which is what I want.

    When running the same code under an Apache web request on the server, the
    Apache error log file contains:

    [Wed Feb 10 12:49:32 2016] main.cgi: $VAR1 = '2016-02-10T12:49:32 --- 7';
    [Wed Feb 10 12:49:32 2016] main.cgi: $VAR1 = '2016-02-11T00:00:00 -> ';
    [Wed Feb 10 12:49:32 2016] main.cgi: $VAR1 = '2016-02-15T00:00:00 -> ';
    [Wed Feb 10 12:49:32 2016] main.cgi: $VAR1 = '2016-02-19T00:00:00 -> ';
    [Wed Feb 10 12:49:32 2016] main.cgi: $VAR1 = '2016-02-22T00:00:00 -> ';
    [Wed Feb 10 12:49:32 2016] main.cgi: $VAR1 = '2016-02-26T00:00:00 -> ';
    [Wed Feb 10 12:49:32 2016] main.cgi: $VAR1 = '2016-02-29T00:00:00 -> ';
    [Wed Feb 10 12:49:32 2016] main.cgi: $VAR1 = '2016-03-04T00:00:00 -> ';
    [Wed Feb 10 12:49:32 2016] main.cgi: $VAR1 = '2016-03-07T00:00:00 -> ';
    [Wed Feb 10 12:49:32 2016] main.cgi: $VAR1 = '2016-03-11T00:00:00 -> ';
    [Wed Feb 10 12:49:32 2016] main.cgi: $VAR1 = '2016-03-14T00:00:00 -> ';
    [Wed Feb 10 12:49:32 2016] main.cgi: $VAR1 = '2016-03-18T00:00:00 -> ';
    [Wed Feb 10 12:49:32 2016] main.cgi: $VAR1 = '2016-03-21T00:00:00 -> ';
    [Wed Feb 10 12:49:32 2016] main.cgi: $VAR1 = '2016-03-25T00:00:00 -> ';
    [Wed Feb 10 12:49:32 2016] main.cgi: $VAR1 = '2016-03-28T00:00:00 -> ';
    [Wed Feb 10 12:49:32 2016] main.cgi: $VAR1 = '2016-04-01T00:00:00 -> ';
    [Wed Feb 10 12:49:32 2016] main.cgi: $VAR1 = '2016-04-04T00:00:00 -> ';
    [Wed Feb 10 12:49:32 2016] main.cgi: $VAR1 = '2016-04-08T00:00:00 -> ';
    [Wed Feb 10 12:49:32 2016] main.cgi: $VAR1 = '2016-04-11T00:00:00 -> ';
    [Wed Feb 10 12:49:32 2016] main.cgi: $VAR1 = '2016-04-15T00:00:00 -> ';
    [Wed Feb 10 12:49:32 2016] main.cgi: $VAR1 = '2016-04-18T00:00:00 -> ';
    [Wed Feb 10 12:49:32 2016] main.cgi: $VAR1 = '2016-04-22T00:00:00 -> ';
    [Wed Feb 10 12:49:32 2016] main.cgi: $VAR1 = '2016-04-25T00:00:00 -> ';
    [Wed Feb 10 12:49:32 2016] main.cgi: $VAR1 = '2016-04-29T00:00:00 -> ';
    [Wed Feb 10 12:49:32 2016] main.cgi: $VAR1 = '2016-05-02T00:00:00 -> ';
    [Wed Feb 10 12:49:32 2016] main.cgi: $VAR1 = '2016-05-06T00:00:00 -> ';
    [Wed Feb 10 12:49:32 2016] main.cgi: $VAR1 = '2016-02-10T12:49:32 --- 21';
    [Wed Feb 10 12:49:32 2016] main.cgi: $VAR1 = '2016-02-11T00:00:00 -> ';
    [Wed Feb 10 12:49:32 2016] main.cgi: $VAR1 = '2016-02-13T00:00:00 -> ';
    [Wed Feb 10 12:49:33 2016] main.cgi: $VAR1 = '2016-02-20T00:00:00 -> ';
    [Wed Feb 10 12:49:33 2016] main.cgi: Can't call method "is_infinite" on an
    undefined value at /usr/local/share/perl/5.14.2/DateTime/Event/Recurrence.pm
    line 870.

    The initial call is for 7 day delivery estimate followed by a 21 day
    delivery estimate. Since both of these are under 21 days, they run the 25
    day estimate (which I was Memoizing to save from calling it repeatedly...)
    The Error I think is inconsequential to the issue I'm concerned with. If
    you look at the dates logged out, it prints the Monday and Friday dates and
    I can't figure out why. On the second call, it logs out Friday then tries
    Sunday (which isn't in the recurrence range) followed by the next Sunday
    which then eventually fails.

    I've verified that the following packages are updated on the server (Ubuntu
    12.04):

    DateTime is up to date. (1.21)
    DateTime::Event::Recurrence is up to date. (0.18)
    DateTime::Format::CLDR is up to date. (1.17)
    DateTime::Format::ICal is up to date. (0.09)
    DateTime::Set is up to date. (0.3600)

    The versions match my local copy.

    Server:
    Distributor ID: Ubuntu
    Description: Ubuntu 12.04.5 LTS
    Release: 12.04
    Codename: precise

    Local:
    Distributor ID: Debian
    Description: Debian GNU/Linux testing-updates (sid)
    Release: testing-updates
    Codename: sid

    Perl: v5.14.2 (which I limited to match server version
    since 5.22 is on Debian Testing)


    Do you have any troubleshooting steps I can take to figure out why the
    iterator would only be stepping over Monday and Friday and skipping the
    Tues/Weds/Thur dates? (I've tried removing the range and using an array of
    [1. 2. 3. 4. 5] in the Recurrence to no avail)

    I had used the DateTime::Event::Holiday::US file previously to complement
    the weekday set I am generating and I went through removing all that to
    track down what this problem is.

    Nick

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupdatetime @
categoriesperl
postedFeb 10, '16 at 6:19p
activeFeb 11, '16 at 9:25a
posts2
users2
websitemetacpan.org...

People

Translate

site design / logo © 2019 Grokbase