Class RecordRefExtensions
- Namespace
- DatabentoDotNet.Dbn
- Assembly
- DatabentoDotNet.Dbn.dll
The date half of a record's index timestamp: the calendar day a symbol map is keyed by.
public static class RecordRefExtensions
- Inheritance
-
RecordRefExtensions
- Inherited Members
Remarks
Port of upstream's Record::index_date (record/traits.rs:68-70), which is
index_ts().map(|dt| dt.date()) — the record's own primary timestamp, reduced to its UTC
date. IndexTs already carries the per-record-type choice between
ts_recv and ts_event, so everything here is the conversion and nothing else.
Extension methods on RecordRef rather than members on
IRecord<TSelf>, and only on RecordRef. Upstream's
index_date() is a default method on the Record trait, so it reaches every record
type; the direct .NET translation does not exist. An interface member would be twenty-one
copies of one line, and a default interface member cannot replace them — calling one on a
record struct needs either boxing or a generic constraint, and boxing a 520-byte
InstrumentDefMsg to read a date is the copy this codec exists to avoid. A
generic extension method cannot take its receiver by in at all (CS8338, and
C# 14's extension blocks keep the restriction as CS9301), so it would copy the record by
value for the same 520 bytes.
For a concrete record struct, the conversion is already a documented one-liner:
DbnTime.TryToUtcDate(def.IndexTs, out var date). It is the same length as a helper
would be, it reads the field in place off a ref readonly,
and it goes through the one sentinel-checking crossing rather than adding a second name for
it. What RecordRef gets here that a concrete struct does not need is the rtype
dispatch — hiding "which timestamp does this record type index on" behind one call is the
whole value, and a concrete struct has already answered that question by being concrete.
WithTsOut<T> is covered by the same one-liner through
IndexTs, which forwards to the wrapped record unchanged —
ts_out is the gateway's send time and never an index timestamp.
Methods
IndexDate(RecordRef)
The UTC calendar date this record indexes on.
public static LocalDate IndexDate(this RecordRef record)
Parameters
recordRecordRefThe record to read.
Returns
- LocalDate
The UTC date.
Remarks
ToUtcDate(ulong) answers the same failure with an
ArgumentOutOfRangeException naming its unixNanoseconds parameter.
That is right there and wrong here: this overload takes no timestamp argument, so an
ArgumentOutOfRangeException would name a parameter the caller never passed.
The condition is a property of the record, which is what
InvalidOperationException says — the same reading
TsOut already gives it.
Exceptions
- InvalidOperationException
The record's index timestamp is UndefTimestamp, so it has no date. Use TryIndexDate(RecordRef, out LocalDate) where a record without one is expected.
TryIndexDate(RecordRef, out LocalDate)
The UTC calendar date this record indexes on, unless its index timestamp is DBN's undefined sentinel.
public static bool TryIndexDate(this RecordRef record, out LocalDate date)
Parameters
recordRecordRefThe record to read.
dateLocalDateReceives the UTC date, or default when the record's index timestamp is UndefTimestamp.
Returns
Remarks
This is the date TryGetSymbol(LocalDate, uint, out string?) is
keyed by. Prefer it to converting TsEvent yourself: most
schemas index on ts_recv, and the two can fall on opposite sides of UTC midnight,
so keying on ts_event returns the previous day's symbol — or nothing — with nothing
anywhere looking broken.