When subtracting or adding months, DateTime does not know whether a month has 28, 29, 30, or 31 days. It simply subtract/add the number of specified months.

Add 1 month to June 15, July 15, Aug 15, Sep 15 and you get July 15, Aug 15, Sep 15, Oct 15 Add 30 days and the answer will not necessarily agree with the above. Add 30 days to July 15 and you get Aug 14

Add 1 month to Feb 28  and you get March 28
Subtract 1 month from Feb 28 and you get Jan 28

----- Original Message ----- From: "Rick Measham" <[EMAIL PROTECTED]>
To: "datetime" <datetime@perl.org>
Sent: Monday, June 13, 2005 8:22 PM
Subject: DT::Duration behaviour .. LSB or MSB?


It seems that I've found where things are going wrong. DateTime must have gone from MSB to LSB math.

When you ask me to subtract 1 month, 14 days from something, I'd take off the month first. MSB. And (if my tests used to work, which I know they did) must have been the way DT:D used to work.

However, the current distro evidently works the other way and subtracts the days and THEN the months. Attached is a test script that shows the problem.

This is not a bug as must as an unexpected behaviour. I wonder if there's some way to allow the user to choose the behaviour? $datetime->add_lsb() and $datetime->add_msb()? (as well as choosing one as the default for simple $datetime->add() and for the overloads)

Cheers!
Rick Measham



use DateTime;
use DateTime::Duration;

my $dt1 = new DateTime( year => 2004, time_zone => 'Australia/Melbourne' ); my $dt2 = new DateTime( year => 2004, time_zone => 'Australia/Melbourne' );

my $dtd1 = new DateTime::Duration( days => -45 );

# dt1 is currently 2004-01-01T00:00:00
# December has 31 full days, which leaves 14 from our 45
# November has 30 days, so subtracting those 14 should leave us at 2004-11-17T00:00:00 # 14 full days of November: 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 # 1 2 3 4 5 6 7 8 9 10 11 12 13 14

my $dtd2 = new DateTime::Duration( months => -1, days => -14 );
# Once again, we subtract December, this time it's our 'one month' leaving us to
# subtract 14 days from November

$dt1 = $dt1 + $dtd1;
$dt2 = $dt2 + $dtd2;

print "DT1: ".$dt1->datetime."\n";
# DT1: 2003-11-17T00:00:00

print "DT2: ".$dt2->datetime."\n\n";
# DT2: 2003-11-18T00:00:00

# So what went wrong? I'm guessing we're starting with the most significant bit
# rather than the least-significant.

# 2004-01-01T00:00:00 - 14 days:
my $dt3 = new DateTime( year => 2004, time_zone => 'Australia/Melbourne' );
my $dtd3 = new DateTime::Duration( days => -14 );

$dt3 = $dt3 + $dtd3;

print "DT3a: ".$dt3->datetime."\n\n";
# DT3a: 2003-12-18T00:00:00

# Now subtract 1 month from that and you get November 18th.

__END__

Reply via email to