Timothy S. Nelson wrote: > I've been working on an extension to Time::Piece which I call > Time::Period. Then you can subtract one Time::Period from another, and it > gives a Time::Seconds which is the length of the first time period minus > the length of the *overlapping* second time period. > > It'd be nice if we had an easy way to shoot this problem in the head > :).
'Time::Period' is DateTime::Span. 'Subtract' is ->complement(). 'Overlapping' is ->intersection. So while you ask in the above for the remaining portion of period 1, I wonder if you want the remaining portion of the two periods. Of course if period 2 is entirely within period 1, the two are the same. #!/usr/bin/perl use DateTime; use DateTime::Span; use Data::Dumper; $date1 = DateTime->new( year => 2003, month => 4, day => 11 ); $date2 = DateTime->new( year => 2003, month => 4, day => 13 ); $date3 = DateTime->new( year => 2003, month => 4, day => 12 ); $date4 = DateTime->new( year => 2003, month => 4, day => 14 ); $time_period_1 = DateTime::Span->from_datetimes( start => $date1, end =>$date2 ); $time_period_2 = DateTime::Span->from_datetimes( start => $date3, end =>$date4 ); # VERSION 1 # When you subtract 1 from 2, you want the length of the # remaining portion of 1: # Period 1: 111111111111111111111111 # Period 2: 222222222222222222222222 # 1 Comp 2: CCCCCCCCCCCC # Result: ^^^^^^^^^^^^ $version_1 = ($time_period_1->complement($time_period_2))->duration; print Dumper( { $version_1->deltas } ); # 1 day ( 2002-04-11 ) # VERSION 2 # You want the length of the remaining portion once the # intersection is removed from the union (a 'nand'): # Period 1: 111111111111111111111111 # Period 2: 222222222222222222222222 # Union: UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU # Intersct: IIIIIIIIIIII # U Comp I: CCCCCCCCCCCC CCCCCCCCCCCC # Result: ^^^^^^^^^^^^ ^^^^^^^^^^^^ $union = $time_period_1->union($time_period_2); $intersection = $time_period_1->intersection($time_period_2); $version_2 = ($union->complement($intersection))->duration; print Dumper( { $version_2->deltas } ); # 2 days ( 2002-04-11 & 2002-04-14 ) [end] Of course, as I said, you'll get exactly the same results for the above if period 1 ->contains period 2. That's because the union of the two periods is the same as period 1 while the intersection is the same as period 2: VERSION 1: # Period 1: 111111111111111111111111111111111111 # Period 2: 222222222222 # 1 Comp 2: CCCCCCCCCCCC CCCCCCCCCCCC # Result: ^^^^^^^^^^^^ ^^^^^^^^^^^^ VERSION 2: # Period 1: 111111111111111111111111111111111111 # Period 2: 222222222222 # Union: UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU # Intersct: IIIIIIIIIIII # U Comp I: CCCCCCCCCCCC CCCCCCCCCCCC # Result: ^^^^^^^^^^^^ ^^^^^^^^^^^^ -- Obviously the reply-to is a fake. Just change the 'spam-' to 'i' so that the result sounds like why you go to an optometerist.