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}; };