---
title: Classify the overlap state of two nullable date ranges
summary: Classify the directional overlap state between two nullable-end ranges.
status: draft
owner: saif-docgen
last_reviewed: 2026-09-15
library: SAIF.Framework.Common
reference_type: package
operation_id: OP-006
trigger: Caller needs a categorical (not boolean) overlap classification where the end date may be open
---

# Classify the overlap state of two nullable date ranges

Classify the directional overlap state between two nullable-end ranges, triggered when caller needs a categorical (not boolean) overlap classification where the end date may be open.

| Field | Value |
| --- | --- |
| **Operation ID** | OP-006 |
| **Trigger** | Caller needs a categorical (not boolean) overlap classification where the end date may be open |
| **Inputs** | `rangeA`, `rangeB` |
| **Outputs** | `SAIF.Common.Enums.DateRangeOverlapResult` |
| **Primary components** | ``SAIF.Common.Classes.NullableDateRange.GetOverlapState(NullableDateRange rangeA, NullableDateRange rangeB)`` |
| **Entry point** | `Common/SAIF.Common/Classes/NullableDateRange.cs` |

## Steps

1. Initialise the result to `default(DateRangeOverlapResult)`, which is `NoOverlap` (ordinal 0). ([BR-012](../business-rules.md#br-012-the-overlap-of-two-nullable-end-ranges-is-classified-into-exactly-one-of-ten-enumerated-states))
2. If neither range has an end date, return `NeitherEnds`. ([BR-012](../business-rules.md#br-012-the-overlap-of-two-nullable-end-ranges-is-classified-into-exactly-one-of-ten-enumerated-states))
3. If only A is open-ended: return `RangeADoesNotEnd_RangeABetweenRangeBStartAndEnd` when A starts strictly inside B, or `RangeADoesNotEnd_RangeAStartBeforeRangeBStart` when A starts before B. ([BR-012](../business-rules.md#br-012-the-overlap-of-two-nullable-end-ranges-is-classified-into-exactly-one-of-ten-enumerated-states))
4. If only B is open-ended: return `RangeBDoesNotEnd_RangeAStartAfterRangeBStart` when A starts after B, or `RangeBDoesNotEnd_RangeAStartBeforeRangeBStart_RangeAEndAfterRangeBStart` when A starts before B but ends after B starts. ([BR-012](../business-rules.md#br-012-the-overlap-of-two-nullable-end-ranges-is-classified-into-exactly-one-of-ten-enumerated-states))
5. With both ranges closed, compare the start and end pairs to select one of four directional states. ([BR-012](../business-rules.md#br-012-the-overlap-of-two-nullable-end-ranges-is-classified-into-exactly-one-of-ten-enumerated-states))
6. If no branch matched, the initial `NoOverlap` value is returned. ([BR-012](../business-rules.md#br-012-the-overlap-of-two-nullable-end-ranges-is-classified-into-exactly-one-of-ten-enumerated-states))

## Process flow

The following diagram visualizes this operation's control flow.

```mermaid
flowchart TD
	Start([GetOverlapState called]) --> Init["Initialize result to<br>NoOverlap (default)"]
	Init --> D1{"Neither range<br>has end date?"}
	D1 -->|Yes| R1([Return NeitherEnds])
	D1 -->|No| D2{"Only A is<br>open-ended?"}
	D2 -->|Yes| R2(["Return RangeADoesNotEnd_*<br>based on A's start"])
	D2 -->|No| D3{"Only B is<br>open-ended?"}
	D3 -->|Yes| R3(["Return RangeBDoesNotEnd_*<br>based on A's start"])
	D3 -->|No| S1["Both closed: compare<br>start/end pairs"]
	S1 --> D4{"Directional state<br>matched?"}
	D4 -->|Yes| R4(["Return matched<br>directional state"])
	D4 -->|No| R5(["Return initial<br>NoOverlap"])
```

## Failure and edge-case behavior

- No null guard on `rangeA`/`rangeB` — passing null raises `NullReferenceException`.* Ranges with identical start and end dates match no branch and yield `NoOverlap`.

## Related documentation
- [Operations and processes](../operations-processes.md)
- [Business rules](../business-rules.md)

> **Note:** Statements marked with * were inferred from code structure, naming conventions, or contextual evidence where direct confirmation was not available in source artifacts.

## Sources
- `Common/SAIF.Common/Classes/NullableDateRange.cs`
- `Common/SAIF.Common/Enums/DateRangeOverlapResult.cs`
