http://www.perlmonks.org?node_id=942347

brad_nov has asked for the wisdom of the Perl Monks concerning the following question:

Hi monks, I am newbie to perl, And I am looking to write a perl code using Date::Calc to calculate 3 dates based on from and to date For example
from_date:2010-06-01 (yyyy-mm-dd) to_date: 2011-01-01 I want to split the date range 3 equal proportions like from_date:2010-06-01 mid_date_1:2010-09-01 mid_date_2:2010-09-02 to_date:2011-01-01
Thanks for your help. in advance.

Replies are listed 'Best First'.
Re: Split date range into 3 equal parts
by Khen1950fx (Canon) on Dec 08, 2011 at 06:59 UTC
    Class::Date makes it a lot quicker.
    #!/usr/bin/perl -slw use strict; use warnings; use Class::Date qw(date); my $date = new Class::Date; print "from_date: ", date("2010-06-01"); print "mid_date1: ", date("2010-06-01") + '3M' + '1D ' - '1D'; print "mid_date2: ", date("2010-06-01") + '3M' + '1D'; print "to_date: ", date("2010-06-01") + '7M';

      I “fanned” that approach, because, in my humble experience, when you start down the primrose-path of date calculations (in terms of what employees such as salesmen and accountants want to do with them ...), it just gets messier and messier.   But, because so darned many of us have been down that very same primrose-path so many times before, “all the work that went into” modules like this one are darned well worth it.   The client comes back to you with a new twist and you can still say, a la “A Chorus Line” ... “I can do that.”   Priceless.

Re: Split date range into 3 equal parts
by ansh batra (Friar) on Dec 08, 2011 at 04:45 UTC

    use Delta_Days method to calculate number of days between 2 dates
    then divide that figure with 2 or 3 whatever you want(since your post says 3 and the example you have given says 2).
    then use Add_Delta_Days method to get the date from intial date to next date and so on....

Re: Split date range into 3 equal parts
by tobyink (Canon) on Dec 08, 2011 at 09:37 UTC

    Don't know about Date::Calc, but using DateTime...

    use DateTimeX::Auto 0.003 qw/:auto/; my $from = '2010-06-01'; my $to = '2011-01-01'; my $diff = $to->delta_days($from)->in_units('days'); my $mid_date_1 = $from->clone->add(days => $diff/3); my $mid_date_2 = $to->clone->subtract(days => $diff/3); print <<OUT; from: $from mid 1: $mid_date_1 mid 2: $mid_date_2 to: $to OUT

    UPDATE: Just released 0.003 of DateTimeX::Auto because the script above was crashing on add and subtract.

Re: Split date range into 3 equal parts
by TJPride (Pilgrim) on Dec 08, 2011 at 14:25 UTC
    Using a slightly more lengthy method integrating a module that comes standard with Perl:

    use Time::Local; use strict; use warnings; my ($from, $to, $range); $from = '2010-06-01'; $to = '2011-01-01'; if (!($range = dateRange($from, $to, 3))) { print "Could not calculate.\n"; } else { print "@$range"; } sub dateRange { my ($fd, $td, $n) = @_; my (@range); $range[0] = $fd; $range[$n] = $td; $fd = [split /-/, $fd]; $td = [split /-/, $td]; ### Calculate timestamps from given dates ### Croaks on bad date, so have to eval just in case eval { ### Make sure to use timestamp from middle of day ### to eliminate potential problems with Daylight ### Savings or day rounding $fd = timelocal(undef, undef, 12, $fd->[2], $fd->[1]-1, $fd->[0]); $td = timelocal(undef, undef, 12, $td->[2], $td->[1]-1, $td->[0]); }; return if $@; ### Calculate intermediate timestamps ### Reverse from timestamps back to dates for (1..($n-1)) { @_ = localtime($fd + ($td - $fd) / $n * $_); $range[$_] = sprintf('%04d-%02d-%02d', $_[5] + 1900, $_[4] + 1, $_[3]); } return \@range; }