this is the patch, which allows for DateTime::Duration comparisions. It has no error checking for the border cases (yet), but the patched module still passes all tests, so I consider that "good enough". It certainly is good enough for my cases where I have differences that always are far enough apart.
-max
-------- Original Message -------- Subject: DateTime::Duration patch Date: Tue, 11 Nov 2003 15:30:32 +0100 From: Max Maischein <[EMAIL PROTECTED]> To: [EMAIL PROTECTED]
Hello Dave,
after some thinking about how to compare the "inconvertible" units, I came up with an ugly hack that will work for "most" cases - the border cases where it fails, are not yet detected, but I'm working on that. The patch passes all my ad-hoc tests, I'll run it later against the DateTime test suite.
I base the "sign" determination on the fact that every day is at least 23 hours long, and that every month is at least 24*28 hours long (as DST never occurs in february). So I can convert days and months down to minutes and see whether the sign is positive or negative.
-max
sub add_duration { my ( $self, $dur ) = @_;
foreach ( qw( months days minutes seconds nanoseconds ) )
{
$self->{$_} += $dur->{$_};
} # we might have to normalize_nanoseconds before comparing durations
$self->_normalize_nanoseconds if $self->{nanoseconds};
$self->_normalize_sign;return $self; }
sub _normalize_sign {
my $self = shift;
my $minutes = $self->{minutes}; # A day is longer than (or equal to) 23 hours,
# a month is longer than (or equal to) 28 days a 24 hours, as DST is
never in february:
$minutes += $self->{days} * 23 * 60;
$minutes += $self->{months} * 24 * 60 * 28; $self->{sign} = 0 <=> $minutes;
};sub _cmp_datetime {
my ($left,$right,$reverse) = @_;
($left,$right) = ($right,$left) if $reverse;
my $diff = $right - $left;
#warn sprintf "Left is %s days and %s minutes.\n",
$left->delta_days, $left->delta_minutes;
#warn sprintf "Right is %s days and %s minutes.\n",
$right->delta_days, $right->delta_minutes;
#warn "positive"
# if $diff->is_positive;
#warn "negative"
# if $diff->is_negative;
return $diff->{sign};
};