如何使用 Npgsql 从 Postgresql 检索 UTC 日期时间

How can you retrieve a UTC DateTime from Postgresql using Npgsql

我正在使用“带时区的时间戳”列类型并将我的日期时间设置为:

INSERT INTO mytable(col1)
VALUES(timestamp with time zone '2020-07-16 17:45:00.000000+00');

每当我尝试检索我的 DateTimes 时,它们都会被转换为 'local' 类型。

这不是我想要的,它设置为 UTC 日期时间,我希望它返回为 UTC,我不希望它转换为本地进入数据库,也不会返回...这样做就可以了不可能在不引起歧义的情况下到达 UTC。

我试过设置“PGTZ”环境变量;当连接打开时,我还执行了以下 sql:

Connection.ExecuteAsync( "SET TIMEZONE TO 'UTC'" );

我尝试过的任何方法似乎都不起作用,根据各种帖子,它似乎是设计使然: https://github.com/npgsql/npgsql/issues/347

这对我来说似乎是完全错误的,但我希望有人能指出我解决这个问题的方法。

我正在使用 .net5/asp.net 和 Dapper(不是 EFCore)和 Npgsql 版本 4.1.5.

Postgresql timestamptz 实际上并不存储时区,它只是存储 UTC 时的值。这意味着 '2020-07-16 17:45:00.000000+00' 不会在输入时转换为 UTC。如果没有指定时区,它将从 TimeZone 设置轮换为 UTC。在检索时,它会使用 TimeZone 设置旋转回该时区。我怀疑您的设置没有发生在进行时间戳检索的同一会话中。我会尝试 SELECT timestamp_fld AT TIME ZONE 'UTC'

这确实是设计使然,并且在常规文本查询中查询 timestamptz 值时与 PostgreSQL 匹配。如果您使用 fire up psql 或 pgadmin 和 select timestamptz 列,您将看到基于 TimeZone 会话参数的本地时间戳。

如@adrian-klaver所述,timestamptz 不是关于将时区存储在数据库中 - 它是关于在读取和写入时间戳值到数据库时应用时区转换,基于 TimeZone范围。如果您不希望进行任何此类转换,请考虑切换到时间戳(不带时区),并按照惯例将所有时间戳设置为 UTC。