【问题标题】:Now() without timezoneNow() 没有时区
【发布时间】:2014-01-15 17:14:32
【问题描述】:

我有一个added_at 类型的timestamp without time zone 列。我希望它的默认值是当前日期时间但没有时区。函数now() 也返回一个时区。

我该如何解决这个问题?

【问题讨论】:

  • 当前日期时间在哪里?在你的办公桌上?在服务器?在您用户的计算机上?没有时区的日期时间没有多大意义。
  • @MikeW 在它运行的环境中。
  • 考虑使用with timestamp,尤其是当您的代码在任何使用夏令时的地方运行时。或者将时间保存为 UTC,而不是本地时区。您始终可以选择要在哪个时区显示数据。
  • @some,和with timezone有区别吗?
  • 你误会timestamp with time zone。它根本不带时区。它只是绝对 UTC 时间,在 TimeZone 会话变量中转换为本地时间/从本地时间转换。只需使用timestamp with time zone;这几乎总是正确的选择。

标签: postgresql timestamp postgresql-9.2


【解决方案1】:

你可以这样做:

SELECT now() AT TIME ZONE current_setting('TimeZone');
SELECT now() AT TIME ZONE 'Europe/Paris';
SELECT now() AT TIME ZONE 'UTC';

不确定这对“added_at”列有何意义。您几乎总是想要一个绝对时间戳(带时区的时间戳)而不是浮动时间戳。


编辑回应以下几点:

  1. 是的,应该使用带时区的时间戳(绝对时间),除非您有充分的理由不这样做。

  2. 客户端时区由SHOW TimeZonecurrent_setting(...) 给出,如上所示。

请花一些时间浏览一下手册 - 它们很好地涵盖了所有这些内容。

【讨论】:

  • 可能,是的。 1)我应该将列的类型更改为timestamp with time zone吗? 2) 我如何知道运行 postgresql 的机器的当前时区是什么?
【解决方案2】:
SELECT now()::timestamp;

转换将now() 返回的timestamptz 转换为您所在时区中对应的timestamp - 由会话的timezone 设置定义。这也是 standard SQL function LOCALTIMESTAMP 在 Postgres 中的实现方式。

如果您不在多个时区操作,那也可以。否则切换到timestamptzadded_at。有什么区别?

顺便说一句,这一模一样,只是更吵更贵:

SELECT now() AT TIME ZONE current_setting('timezone');

【讨论】:

  • select now()::timestamptz; 更合适
  • @DmitriKosolobov: now() 已经返回 timestamptz,因此 now()::timestamptz 没有任何用处。
  • 这比localtimestamp好吗?
  • now()::timestamp 可能会进行一些转换,但对我来说它不会从本地时区转换为 UTC。但是now() AT TIME ZONE 'UTC'; 做了正确的事。
  • @ThoPaz: now() AT TIME ZONE 'UTC' 返回时区 UTC 的本地时间。 LOCALTIMESTAMPnow()::timestamp 返回会话当前 timezone 设置的本地时间。两种不同的东西!仅当您当前的会话使用 timezone = 'UTC' 运行时才会返回相同的结果。
【解决方案3】:

"Current Date/Time":

CURRENT_TIME 和 CURRENT_TIMESTAMP 传递带有时区的值; LOCALTIME 和 LOCALTIMESTAMP 提供没有时区的值。

【讨论】:

    【解决方案4】:

    2020 年新的原生答案

    在 PostgreSQL 中,如果您只想要当前日期时间,请调用CURRENT_TIMESTAMP() 没有时区,秒字段中的小数位秒字段的点?

    (在 PostgreSQL v12.4 上测试)

    然后使用这个:

    SELECT CURRENT_TIMESTAMP(0)::TIMESTAMP WITHOUT TIME ZONE;
    

    如果您将列的数据类型定义为timestamp(而不是timestamptz),那么您可以存储没有时区的时间戳,在这种情况下您不需要添加@ 987654325@

    像这样:

    CREATE TABLE foo (created timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP(0))
    

    在上面的函数中,0被传递以去除秒字段中的小数。

    【讨论】:

      猜你喜欢
      • 2012-07-06
      • 2012-05-30
      • 1970-01-01
      • 1970-01-01
      • 2012-02-28
      • 2017-12-09
      • 2011-11-08
      • 2017-04-08
      • 2012-01-01
      相关资源
      最近更新 更多