Skip to content

UTC DateTime is not saved correctly when Postgres server is set to time zone other than UTC #2209

@nheilbuth

Description

@nheilbuth

Steps to reproduce

When postgresql.conf has this setting:
timezone = 'Europe/Brussels'
(Europe/Brussels is UTC + 1)

This code will save the timestamp 1 hour too early (and exception will be thrown)

var timestamp = DateTime.UtcNow;

using (var command = new NpgsqlCommand())
{
  var sql = "INSERT INTO testtable (id, timestamp) VALUES (@id, @timestamp)";

  command.Connection = connection;
  command.CommandText = sql;
  command.Parameters.Add(new NpgsqlParameter("timestamp", timestamp));
  command.Parameters.Add(new NpgsqlParameter("id", 1));

  command.ExecuteNonQuery();
}

using (var command = new NpgsqlCommand())
  {
  var sql = "SELECT * FROM testtable WHERE id = @id";

  command.Connection = connection;
  command.CommandText = sql;
  command.Parameters.Add(new NpgsqlParameter("id", 1));

  var reader = command.ExecuteReader();
  if (reader.Read())
  {
    var resultTimestamp = Convert.ToDateTime(reader["timestamp"]);

    if (!Compare(resultTimestamp.ToUniversalTime(), timestamp.ToUniversalTime()))
      throw new Exception("Result was not as expected");
    }
  }

...

 static bool Compare(DateTime dt1, DateTime dt2)
 {
      return dt1.Year == dt2.Year &&
                 dt1.Month == dt2.Month &&
                 dt1.Day == dt2.Day &&
                 dt1.Hour == dt2.Hour &&
                 dt1.Minute == dt2.Minute &&
                 dt1.Second == dt2.Second;
 }

When setting postgresql.conf timezoen to:
timezone = 'UTC'
...the above code works as expected and does not throw an exception

The issue

When saving a DateTime that has Kind = UTC, I expect it to be saved as UTC with the exact hour value being passed.
This is not what happens. If saving the value "yyyy-mm-dd 11:00:00" as UTC the value in postgres will be 11:00:00 as local time and converted to UTC it will be 10:00:00. The expected values is 12:00:00 local and 11:00:00 UTC

Postgres server timezone setting = UTC will produce the correct result. Other timezone settings will not (only tested with 'Europe/Brussels' value).
This issue only exists in NpgSql 4.x
NpgSql 3.x works as expected regardless of server timezone setting

Further technical details

Npgsql version: 4.0/4.3
PostgreSQL version: 9.6
Operating system: Windows 10

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