Table of Contents

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

record RecordRef

The 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

record RecordRef

The record to read.

date LocalDate

Receives the UTC date, or default when the record's index timestamp is UndefTimestamp.

Returns

bool

false when the index timestamp is undefined.

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.