【问题标题】:How can you retrieve a UTC DateTime from Postgresql using Npgsql如何使用 Npgsql 从 Postgresql 检索 UTC 日期时间
【发布时间】:2021-02-21 20:55:18
【问题描述】:

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

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

每当我尝试检索我的 DateTimes 时,它们都会被转换为“本地”类型。

这不是我想要的,它设置为 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。

【问题讨论】:

    标签: c# postgresql datetime npgsql


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

      • 谢谢@Shay,我读到如果你想存储UTC值,你应该使用timestamp with time zone,但我不认为因为我是通过代码控制的,所以我可以在设置之前确保它的UTC价值。我必须说,在所有数据库中,postgres 在这方面似乎过于复杂并且容易出错,所以感谢您的澄清
      • 我同意 PG 有点令人困惑(尽管 FWIW 似乎非常严格地遵循 SQL 标准)。您可能想在带和不带时区的时间戳上阅读this comment of mine;我真的建议使用“按惯例 UTC”
      猜你喜欢
      • 2020-06-02
      • 1970-01-01
      • 2020-06-02
      • 1970-01-01
      • 2020-06-08
      • 2020-08-24
      • 1970-01-01
      • 2014-01-05
      • 2020-02-26
      相关资源
      最近更新 更多