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

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

I need to calculate the difference between 2 dates. I have 2 fields in a text file. I thought I had the dates in the right format.

the error is "Date::Calc::PP::Delta_Days(): Usage: Date::Calc::Delta_Days($year1,$month1,$day1,$year2,$month2,$day2)"

file1 2013,06,21 2013,06,24 2013,06,23 2013,06,28 2013,06,08 2013,06,10 2013,06,23 2013,06,24 2013,06,13 2013,06,18 2013,06,29 2013,06,17 2013,06,19 2013,06,13 2013,06,18 2013,06,29 2013,06,06 2013,06,10 2013,06,10 2013,06,26 2013,06,23 2013,06,29 2013,06,06 2013,06,10

my script - if possible would like to fill the empty spaces with the last day of the current month date

#!/usr/bin/perl # use strict; use warnings; use Date::Calc qw( Delta_Days ); my $cnt = 0; open (my $file, '<', (@ARGV)) or die $!; while (<$file>) { my @dates = split '\t', $_; $cnt++; # printf "%-10s %-10s\n", # $dates[0], # $dates[1]; my @dates1 = (); my @dates2 = (); push (@dates1, $dates[0]); push (@dates2, $dates[1]); my $diff = Delta_Days(@dates1, @dates2); print $diff, "\n"; #printf "%-12s %-12s\n", #@dates1, #@dates2; } close $file; print $cnt, "\n"; exit;

Thanks so much for your help, it is a life-saver

Replies are listed 'Best First'.
Re: Trouble with Dates
by Preceptor (Deacon) on Jul 09, 2013 at 20:53 UTC

    The problem here, is that you're feeding 'Delta_Days' an array that contains a comma separated string. Which is why it doesn't work - you're doing:

    Delta_Days ( "2013,06,06", "2013,06,10" );

    You need another 'split' and do so on a 'comma'. E.g.:

    my ( $firstdate, $seconddate ) = split ( /\t/ ); my @dates1 = split ( ",", $firstdate ); my @dates2 = split ( ",", $seconddate );

    You could probably do a bit more to smooth it out a bit further, but that's where you're going wrong. (I think - I've not run this code)

Re: Trouble with Dates
by poj (Abbot) on Jul 09, 2013 at 21:47 UTC
    Try
    use strict; use warnings; use Date::Calc qw( Delta_Days Today Days_in_Month ); my $cnt = 0; # work out end of current month my ($y,$m,$d) = Today(); my $mth_end = sprintf "%04d,%02d,%02d",$y,$m,Days_in_Month($y,$m); while (<DATA>) { my @dates = split '\s+', $_; $cnt++; # fill empty dates with month end my @ymd1 = split ',',$dates[0] //= $mth_end; my @ymd2 = split ',',$dates[1] //= $mth_end; my $diff = Delta_Days(@ymd1, @ymd2); print "$dates[0] $dates[1] $diff \n"; } print $cnt, "\n";
    poj

      This worked great!! thx poj

      if i wanted to find previous month's last day how would i go about that..thx

        To get last day of previous month add -1 days to the 1st of the current month.
        #perl use strict; use Date::Calc qw( Delta_Days Today Days_in_Month Add_Delta_Days); # add Add_Delta_Days my ($y,$m,$d) = Today(); # Add_Delta_Days #($year,$month,$day) = Add_Delta_Days($year,$month,$day,$Dd); my $prev_mth_end = sprintf "%04d,%02d,%02d", Add_Delta_Days($y,$m,1,-1); print $prev_mth_end;
        All the function are documented in Date::Calc.
        poj
Re: Trouble with Dates
by mtmcc (Hermit) on Jul 10, 2013 at 10:40 UTC
    Or using localtime() (but poj's is probably better):

    #!/usr/bin/perl use strict; use warnings; my $datafile = $ARGV[0]; #get date from localtime my @date = localtime(time); my $month = sprintf("%02d", ($date[4] + 1)); my $year = 1900 + $date[5]; my $day = sprintf("%02d", $date[3]); my %months = ("01", "31", "02", "28", "03", "31", "04", "30", "05", "3 +1", "06", "30", "07", "31", "08", "31", "09", "30", "10", "31", "11", + "30", "12", "31"); # in case of leap year %months = ("01", "31", "02", "29", "03", "31", "04", "30", "05", "31", + "06", "30", "07", "31", "08", "31", "09", "30", "10", "31", "11", "3 +0", "12", "31") if $year%4 == 0; my @array = (); open (FILE, "<", $datafile); while (<FILE>) { @array = split (" ", $_); print STDOUT "$_" if ((@array==2)||($array[0] =~ /[a-zA-Z]/)); print STDOUT "$array[0]\t$year,$month,$months{$day}\n" if ((@a +rray==1) && ($array[0] !~ /[a-zA-Z]/)); } close FILE;

Re: Trouble with Dates
by Cristoforo (Curate) on Jul 22, 2013 at 01:44 UTC
    Here is a solution also using Date::Calc.
    #!/usr/bin/perl use strict; use warnings; use 5.014; use Date::Calc qw( Delta_Days Days_in_Month ); while (<DATA>) { my ($y1, $m1, $d1, $y2, $m2, $d2) = split /\D+/; $y2 ||= $y1; $m2 ||= $m1; $d2 ||= Days_in_Month($y2, $m2); # last day in current month say Delta_Days($y1, $m1, $d1, $y2, $m2, $d2); }