Table of Contents

Struct ReferenceDateTimeRange

Namespace
DatabentoDotNet.Reference
Assembly
DatabentoDotNet.Reference.dll

The request range the three reference get_range endpoints take: an inclusive Start instant and an optional exclusive End. Omit the end and the response runs to the end of the data.

public readonly record struct ReferenceDateTimeRange : IEquatable<ReferenceDateTimeRange>
Implements
Inherited Members

Remarks

This exists because DateTimeRange cannot express an absent end, and not for any reason to do with what the reference API means by a range. That type requires both ends and rejects an empty one at construction, which is right for the historical endpoints that carry it — every one of them names a bounded query. The reference endpoints do not: upstream's End renderer pushes nothing at all when the end is None (databento-rs/src/reference.rs:234-250), and an end= with an empty value is a different request from no end at all.

That the end is exclusive is upstream's doc comment, not a probe. reference/security.rs:101-105, corporate.rs:128-132 and adjustment.rs:59-63 each say "the exclusive end time of the request range", and nothing in either library has asked the server. That is the exact shape of the assumption #45 found to be false for get_dataset_condition and #46 found to be true for three others — each only because someone asked. So this documents the end as documented exclusive and unprobed, the way DateTimeRange already does for timeseries.get_range and batch.submit_job.

#57 built the probe, ran it, and could not get an answer — so "unprobed" above is now a measured state rather than an unopened question. RealReferenceRequestTests.CorporateActionsGetRange_ReadsTheRangeEndAsExclusive requests a window, takes the latest event_date in it, re-requests ending at midnight UTC on that date and reports whether those rows survived — an experiment that differs by whole rows rather than by a nanosecond. On 2026-08-29 the account it ran under answered 403 license_reference_dataset_no_subscription: reference data is a separate Databento product, and three separate subscriptions at that. The experiment is written, gated on DATABENTO_REFERENCE_REQUEST, and runs the moment an entitled key exists.

Until then this end is documented exclusive on upstream's word alone, which is precisely the standing of the end_date that #45 found to be wrong. Do not promote it to a fact by citing this comment.

It lives in this package rather than beside DateTimeRange. No historical endpoint accepts an open-ended range, so putting it there would add a public type to a package that nothing in that package consumes — and would stand next to DateTimeRange inviting a caller to reach for the wrong one. Upstream draws the same line: its Start and End renderers are declared in reference.rs, not shared down from historical the way AddToForm and handle_zstd_jsonl_response are. The direction of the dependency makes From(DateTimeRange) possible from here and would not make the reverse possible from there.

The factory set is deliberately four, where DateTimeRange has five. StartingAt(Instant) is the open range this type exists for; Between(Instant, Instant) is the closed one; FromUnixNanoseconds(long, long?) is the wire crossing; and From(DateTimeRange) converts. There is no OnDay, Including or Spanning here, because DateTimeRange already has all three and From(DateTimeRange) is one call — duplicating them would mean two places to keep the day-boundary and off-by-one-nanosecond rules right instead of one.

Properties

End

The exclusive end instant, or null for a range that runs to the end of the data.

public Instant? End { get; }

Property Value

Instant?

Remarks

null here is also what default carries, so this alone does not distinguish an open range from a value no factory built. The accessors that render what goes on the wire do — see ToFormParameters().

EndUnixNanoseconds

This range's End in Unix nanoseconds, or null when the range is open-ended — in which case the end parameter is not sent at all.

public long? EndUnixNanoseconds { get; }

Property Value

long?

Exceptions

InvalidOperationException

This is a default ReferenceDateTimeRange value.

OverflowException

End is too far from the Unix epoch (roughly beyond the year 2262) for its nanosecond count to fit in a long. See CLAUDE.md, "Dates and times".

Start

The inclusive start instant. Always present.

public Instant Start { get; }

Property Value

Instant

StartUnixNanoseconds

This range's Start, rendered the way the reference API's start parameter expects it: Unix nanoseconds.

public long StartUnixNanoseconds { get; }

Property Value

long

Exceptions

InvalidOperationException

This is a default ReferenceDateTimeRange value.

OverflowException

Start is too far from the Unix epoch (roughly beyond the year 2262) for its nanosecond count to fit in a long. See CLAUDE.md, "Dates and times".

Methods

Between(Instant, Instant)

A half-open range: start is included, end is not.

public static ReferenceDateTimeRange Between(Instant start, Instant end)

Parameters

start Instant

The inclusive start instant.

end Instant

The exclusive end instant.

Returns

ReferenceDateTimeRange

The range.

Exceptions

ArgumentException

end is not strictly after start.

From(DateTimeRange)

Widens a historical DateTimeRange into this type, keeping both ends. The result is never open-ended, because the range it came from could not be.

public static ReferenceDateTimeRange From(DateTimeRange range)

Parameters

range DateTimeRange

The historical range.

Returns

ReferenceDateTimeRange

The range.

Remarks

This is the conversion a caller who already holds a DateTimeRange — from OnDay(LocalDate), Including(Instant, Instant), Spanning(Instant, Duration), or a metadata query they are about to repeat against the reference API — reaches for instead of rebuilding it. There is no conversion back, and that is not an omission: an open range has no DateTimeRange to become.

Exceptions

ArgumentException

range is a default DateTimeRange value, which names no range.

FromUnixNanoseconds(long, long?)

A range built directly from Unix-nanosecond integers, the representation in which the reference API's start and end parameters travel on the wire.

public static ReferenceDateTimeRange FromUnixNanoseconds(long startUnixNanoseconds, long? endUnixNanoseconds)

Parameters

startUnixNanoseconds long

Nanoseconds since the UNIX epoch, inclusive.

endUnixNanoseconds long?

Nanoseconds since the UNIX epoch, exclusive, or null for a range that runs to the end of the data.

Returns

ReferenceDateTimeRange

The range.

Remarks

Exact where a BCL DateTimeOffset pair would not be: two Unix-nanosecond integers one apart collapse to the same DateTimeOffset (100 ns resolution) and round-trip through Instant unchanged. See CLAUDE.md, "Dates and times", and FromUnixNanoseconds(long, long), which carries the same guarantee for the historical endpoints.

Exceptions

ArgumentException

endUnixNanoseconds is not strictly after startUnixNanoseconds.

StartingAt(Instant)

A range starting at start and running to the end of the data: the end parameter is not sent.

public static ReferenceDateTimeRange StartingAt(Instant start)

Parameters

start Instant

The inclusive start instant.

Returns

ReferenceDateTimeRange

The range.

ToFormParameters()

Renders this range as the start and end form fields the reference get_range endpoints post — one field when the range is open, two when it is not.

public IReadOnlyList<KeyValuePair<string, string>> ToFormParameters()

Returns

IReadOnlyList<KeyValuePair<string, string>>

One or two form fields, start first.

Remarks

The branch lives here rather than in each of the three parameter sets that carry a range, so there is one place to get it right instead of three. Upstream reaches the same arrangement through its AddToForm<End> impl (reference.rs:242-250), which the three get_range functions each call rather than re-deriving.

An open range yields the key set {start}. It does not yield {start, end} with an empty value: end= is a different request, and one this library never sends.

Exceptions

InvalidOperationException

This is a default ReferenceDateTimeRange value.

OverflowException

An end of the range is too far from the Unix epoch (roughly beyond the year 2262) for its nanosecond count to fit in a long.

ToString()

A debugging-oriented description, printing Start and End directly rather than through StartUnixNanoseconds/EndUnixNanoseconds.

public override string ToString()

Returns

string

The description.

Remarks

Hand-written for the reason ToString() is: the compiler-synthesized record ToString prints every public property, including the two that refuse to render a default value — which would make a supposedly inert ToString() call throw. It goes one step further than that sibling and says (default) outright, because printing this type's default as a start of 1970-01-01T00:00:00Z with no end would look exactly like a range someone meant to build.