Daterange: Clarified supported cases

This commit is contained in:
Paul Beckingham 2016-04-16 11:53:30 -04:00
parent 85f08200df
commit 091587f8cd
2 changed files with 101 additions and 28 deletions

View file

@ -81,22 +81,26 @@ bool Daterange::isEnded () const
// Detect the following overlap cases:
//
// this |--------|
// other |--------| false [1]
// other |--------| true
// other |----| true
// other |--------| true
// other |--------| false [2]
// other |-------------| true
// other |... true
// other |... true
// other |... false [3]
// A |--------|
// B |--------|
// C |----|
// D |--------|
// E |--------|
// F |-------------|
// G |...
// H |...
// I |...
//
// this |...
// other |--------| false [4]
// other |--------| true
// other |----| true
// other |... true
// other |... true
// A |--------|
// B |--------|
// C |----|
// D |--------|
// E |--------|
// F |-------------|
// G |...
// H |...
// I |...
//
bool Daterange::overlap (const Daterange& other) const
{
@ -104,12 +108,12 @@ bool Daterange::overlap (const Daterange& other) const
! other.isStarted ())
return false;
// [1], [4] Other range ends before this range starts.
// Other range ends before this range starts.
if (other.isEnded () &&
other.end () <= start ())
return false;
// [2], [3] Other range starts after this range ends.
// Other range starts after this range ends.
if (isEnded () &&
other.start () >= end ())
return false;
@ -121,18 +125,23 @@ bool Daterange::overlap (const Daterange& other) const
// Calculate the following intersection cases:
//
// this |--------|
// other |--------|
// other |----|
// other |--------|
// other |-------------|
// other |...
// other |...
// B |--------|
// C |----|
// D |--------|
// F |-------------|
// G |...
// H |...
//
// this |...
// other |--------|
// other |----|
// other |...
// other |...
// A |--------|
// B |--------|
// C |----|
// D |--------|
// E |--------|
// F |-------------|
// G |...
// H |...
// I |...
//
Daterange Daterange::intersect (const Daterange& other) const
{
@ -162,3 +171,65 @@ Daterange Daterange::intersect (const Daterange& other) const
}
////////////////////////////////////////////////////////////////////////////////
// Consider the following overlap cases:
//
// this |--------|
// B |--------|
// C |----|
// D |--------|
// F |-------------|
// G |...
// H |...
//
// this |...
// A |--------|
// B |--------|
// C |----|
// D |--------|
// E |--------|
// F |-------------|
// G |...
// H |...
// I |...
//
std::vector <Daterange> Daterange::subtract (const Daterange& other) const
{
std::vector <Daterange> results;
if (overlap (other))
{
// B C D F G H
if (start () < other.start ())
{
// C D H
results.push_back (Daterange (start (), other.start ()));
if (other.isEnded () &&
end () > other.end ())
{
// C
results.push_back (Daterange (other.end (), end ()));
}
}
else
{
// B F G
if (other.isEnded () &&
end () > other.end ())
{
// B
results.push_back (Daterange (other.end (), end ()));
}
}
}
// Non-overlapping subtraction is a nop.
else
{
results.push_back (*this);
}
return results;
}
////////////////////////////////////////////////////////////////////////////////

View file

@ -28,6 +28,7 @@
#define INCLUDED_DATERANGE
#include <Datetime.h>
#include <vector>
class Daterange
{
@ -46,10 +47,11 @@ public:
bool isEnded () const;
bool overlap (const Daterange&) const;
Daterange intersect (const Daterange&) const;
std::vector <Daterange> subtract (const Daterange&) const;
private:
Datetime _start {0};
Datetime _end {0};
Datetime _start {0};
Datetime _end {0};
};
#endif