--- Duration.pm	06 Jan 2006 09:53:26 -0800	1.50
+++ Duration.pm	08 Jan 2006 14:47:14 -0800	
@@ -15,6 +15,7 @@
 use constant MAX_NANOSECONDS => 1_000_000_000;  # 1E9 = almost 32 bits
 
 my @all_units = qw( months days minutes seconds nanoseconds );
+my @norm_units = qw( years months days hours minutes seconds nanoseconds );
 
 # XXX - need to reject non-integers but accept infinity, NaN, &
 # 1.56e+18
@@ -34,7 +35,7 @@
                                              regex => qr/^(?:wrap|limit|preserve)$/ },
                          } );
 
-    my $self = bless {}, $class;
+    my $self = bless { norm => \%p }, $class;
 
     $self->{months} = ( $p{years} * 12 ) + $p{months};
 
@@ -78,10 +79,13 @@
           || $self->{nanoseconds} eq DateTime::NAN()
         );
 
+    my $norm = $self->{norm};
     my $seconds = $self->{seconds} + $self->{nanoseconds} / MAX_NANOSECONDS;
-    $self->{seconds} = int( $seconds );
-    $self->{nanoseconds} = $self->{nanoseconds} % MAX_NANOSECONDS;
-    $self->{nanoseconds} -= MAX_NANOSECONDS if $seconds < 0;
+    $self->{seconds} = $norm->{seconds} = int( $seconds );
+    $self->{nanoseconds} = $norm->{nanoseconds}
+        = $self->{nanoseconds} % MAX_NANOSECONDS;
+    $self->{nanoseconds} = $norm->{nanoseconds}
+        -= MAX_NANOSECONDS if $seconds < 0;
 }
 
 sub clone { bless { %{ $_[0] } }, ref $_[0] }
@@ -115,6 +119,11 @@
     map { $_ => $_[0]->{$_} } @all_units;
 }
 
+sub norm_deltas
+{
+    map { $_ => $_[0]->{$_} } @norm_units;
+}
+
 sub in_units
 {
     my $self  = shift;
@@ -201,9 +210,10 @@
     my $self = shift;
 
     my %new;
-    foreach my $u (@all_units)
+    my $norm = $self->{norm};
+    foreach my $u (@norm_units)
     {
-        $new{$u} = $self->{$u};
+        $new{$u} = $norm->{$u};
         # avoid -0 bug
         $new{$u} *= -1 if $new{$u};
     }
@@ -220,6 +230,12 @@
         $self->{$u} += $dur->{$u};
     }
 
+    my ($self_norm, $dur_norm) = ( $self->{norm}, $dur->{norm} );
+    foreach my $u (@norm_units)
+    {
+        $self_norm->{$u} += $dur_norm->{$u};
+    }
+
     $self->_normalize_nanoseconds if $self->{nanoseconds};
 
     return $self;
@@ -246,9 +262,11 @@
     my $self = shift;
     my $multiplier = shift;
 
+    my $norm = $self->{norm};
     foreach my $u (@all_units)
     {
         $self->{$u} *= $multiplier;
+        $norm->{$u} *= $multiplier;
     }
 
     $self->_normalize_nanoseconds if $self->{nanoseconds};
