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

Any Date::Calc gurus in the house? I'm trying to do something so simple I just must be completely wrong, because the result isn't what I'm expecting.

Just for giggles, I simply want the Years, Months and Days between my dob and now. Using Date::Calc version 5.

use strict; use Date::Calc qw(Delta_YMD Today); sub version { my $format = shift || "%D.%02d.%02d"; my ($year, $month, $day) = Today; my ($dy, $dm, $dd) = Delta_YMD(1973, 7, 19, $year, $month, $ +day); my $version = sprintf($format, $dy, $dm, $dd); return $version; }; print version();

I get 29.02.-15

-15 ? I would think first of all, there should be no negative results as long as the dates are input in the right order, and then, it would be all negative or all positive.

What I'm really after is 29.01.15 (years, months, days)
Multiplying days times -1 and subtracting 1 form the months does it. :-) Or changing the 7 to an 8 in Delta_YMD. But what am I really missing here? Today is returning the correct values also.

* feeling clueless today *

Replies are listed 'Best First'.
Re: Date::Calc / Delta_YMD funkyness?
by mojotoad (Monsignor) on Sep 04, 2002 at 23:37 UTC
    Date::Calc is just working as advertised. In the docs, it's stated that Delta_YMD returns the vector [y2 - y1], [m2 - m1], [d2 - d1]. So the negative value is understandable.

    Even taking absolute values, however, this is still sort of worthless because it lacks accountability for months with differing day counts, etc. The real way to do it is subtract your seconds since epoch and work back to YMD from the result.

    Here's an example using Time::Piece and Time::Seconds:

    #!/usr/bin/perl use Time::Piece; use Time::Seconds; $bd_time = Time::Piece->strptime("1973/07/19", "%Y/%m/%d"); $now = localtime(time); $diff = $now - $bd_time; $years = int($diff->years); $diff -= $years * ONE_YEAR; $months = int($diff->months); $diff -= $months * ONE_MONTH; $days = int($diff->days); print "$years years, $months months, $days days\n";

    Today that yields 29 years, 1 month, 17 days. Use Lingua::EN::Inflect to season your output. Serves 4.

    Matt

      "...that Delta_YMD returns the vector [y2 - y1], [m2 - m1], [d2 - d1]."

      Thank for the ClueBy4. Read it a few times, just didn't register clearly. I guess I took "Delta" to be a little bit more literal than plain ole subtraction.

      Many thanks for the code snippet. Time to study it for a while.

Re: Date::Calc / Delta_YMD funkyness?
by sauoq (Abbot) on Sep 04, 2002 at 23:35 UTC

    The manual says about Delta_YMD:

    This function returns the vector ( $year2 - $year1, $month2 - $month1, $day2 - $day1 ) An error occurs if any of the two dates is invalid.

    Which is exactly what it is doing but, obviously, is not what you want. You would be better off using the Delta_Days() function which will return the difference between the dates in days. This actually makes more sense because expressing the difference in years, months, and days is a bit ambiguous due to the fact that neither a year nor a month has a constant number of days.

    -sauoq
    "My two cents aren't worth a dime.";