X Tutup
Skip to content

unable to read NodaTime values #2251

@mickeyjf

Description

@mickeyjf

I am unable to read NodaTime values despite using the exact example in the Npgsql documentation here:

https://www.npgsql.org/doc/types/nodatime.html

Attempting to read a field as an Instant or as a DateTimeOffset throws an InvalidCastException.

I am able to read as a BCL DateTime, but the value is returned dependent on the Windows Regional formatting (for example, "01-01-02000") rather than as ISO. Formatting on any given Windows box is outside of my control and can't be depended on.

My goal is to have all DateTime values stored in the DB strictly as UTC ISO and to be able to round-trip them in and out of the DB that way. I am following what I understand to be Jon Skeet's advice here : https://stackoverflow.com/questions/31477681/what-is-the-best-way-to-store-nodatime-based-values-in-postgresql

Problem # 1 - I am only able to read timestamps as BCL data types.
Problem # 2 - Even then, Npgsql appears to be depending on the Windows Regional formatting and I cannot parse the returned values as ISO.

I am currently developing this on Windows but will be running on Linux.

/--------------------------------------/
Postgresql 9.6
Npgsql version 4.0.3
Windows 7 Professional (Windows 6.1.7601.65536 (64-bit))

MonoDevelop Version 7.8
Runtime: Microsoft .NET 4.0.30319.42000

/--------------------------------------/

I have not tested the example code - it is copy-pasted and stripped down from my actual project but should be enough to throw light on the issue.

Table like:

CREATE TABLE session_times
(
    name text,
    time_stamp timestamp without time zone
)

Data entered like:

SetSessionTime("last_backup", SystemClock.Instance.GetCurrentInstant());

public void SetSessionTime(string Name, Instant TheTime)
        {
			string sql = string.Format("UPDATE session_times SET time_stamp = '{0}' WHERE name = '{1}'",
									   TheTime.ToDateTimeOffset(), Name);
			ExecuteNonQuery(sql);
        }

The above works as expected - the table is updated with the timestamp.

However, per:

https://www.npgsql.org/doc/types/nodatime.html

using (var cmd = new NpgsqlCommand("SELECT time_stamp FROM session_times WHERE name = 'last_backup'", conn))
using (var reader = cmd.ExecuteReader())
{
    reader.Read();
    var instant = reader.GetFieldValue<Instant>(0);
}

This query works as expected in pgAdmin4.
When run in the project, accessing Postgres via Npgsql, it fails with :

{System.InvalidCastException: Can't cast database type timestamp to Instant    
at Npgsql.NpgsqlDefaultDataReader.GetFieldValue[T](Int32 column) ....etc}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      X Tutup