EFCore.SqlServer.NodaTime icon indicating copy to clipboard operation
EFCore.SqlServer.NodaTime copied to clipboard

Duration with values >= 24h

Open Isitar opened this issue 2 years ago • 3 comments

Hello

Since your DataType for a Duration is time Values >= 24h are not supported. Do you plan on changing it or at least hint at it in the documentation?

Isitar avatar Feb 06 '24 10:02 Isitar

@Isitar - The main reason for choosing this type was so that queries would translate to SQL and just work with where clauses. I'm open to suggestions or pull requests if you feel there's a way to accomplish this by storing it as a string or another type. In the meantime, I can certainly update the documentation to reflect the current limitation.

StevenRasmussen avatar Feb 06 '24 18:02 StevenRasmussen

thanks for the update in the doc 👍

One option would be to store it as datetime2, this seems to work as long as the duration is less than a month this article https://www.sqlteam.com/articles/working-with-time-spans-and-durations-in-sql-server gives more insight.

i'm not sure if it really works with everything like dailight-saving, leap year etc.

Isitar avatar Feb 07 '24 09:02 Isitar

I am also running into this, my workaround will probably be to store the duration as INT4 (count of minutes) and handle mapping myself.

From the NodaTime docs for Duration: "A duration is a length of time defined by an integral number of nanoseconds".

While for many applications this is probably overkill, but I think a Duration should probably map to BIGINT since that will be pretty easy and support a large range of Duration values.

In NodaTime, Duration's storage is implemented with two fields: Int32 days and Int64 nanoOfDay.

Using ToInt64Nanoseconds (shown below) to map from Duration => BIGINT should give around +/-292 years of range with nanosecond resolution (as documented below).

To read it back into a Duration use public static Duration FromNanoseconds(long nanoseconds)

/// <summary>
/// Conversion to an <see cref="Int64"/> number of nanoseconds. This will fail if the number of nanoseconds is
/// out of the range of <c>Int64</c>, which is approximately 292 years (positive or negative).
/// </summary>
/// <exception cref="System.OverflowException">The number of nanoseconds is outside the representable range.</exception>
/// <returns>This duration as a number of nanoseconds, represented as an <c>Int64</c>.</returns>
public long ToInt64Nanoseconds() ...

corydambach avatar Aug 21 '24 16:08 corydambach