如何从我的时区的Postgres获取日期

问题描述 投票:0回答:3

我尝试在主机上使用TypeORM和Postgres部署JS应用程序。在本地,我有一个Postgress数据库,因此可以在自己的TZ中运行。远程主机的系统时间恰好设置为UTC:

$ date
Mon Oct 7 15:45:00 UTC 2019

$ psql
> select localtimestamp;
2019-10-07 15:45:00.123456

我有一个表,其中有一个自动更新的日期(这意味着它在记录更新时也会更新)。

// my.entity.ts
@UpdateDateColumn({type: 'timestamp', name: 'lastUpdate', default: () => 'LOCALTIMESTAMP' })
lastUpdate: Date;

在CEST CEST 12:00插入一行:

> select "lastUpdate" from myTable;
2019-10-07 10:00:00.000000+00

无论服务器时间如何,我都希望在我的时区(CEST)中确定日期,因此它应该返回我2019-10-07 12:00。我宁愿不对任何技巧进行硬编码,因为它也可以在我的CEST计算机上使用。

Postgress具有所有信息:

> show timezone;
UCT
  • 它知道它在UTC时间运行
  • 我可以告诉我想要哪个时区

因此,我希望将其轻松转换为我要求的格式很容易。但是,我发现以下示例似乎无效:

> select ("lastUpdate" at time zone 'CEST') from myTable;
2019-10-07 08:00:00.000000+00

> select timezone('CEST', "lastUpdate") from myTable;
2019-10-07 08:00:00.000000+00

有一种方法可以正确解决,那就是指定当前时区:

> select ("lastUpdate" at time zone 'UTC' at time zone 'CEST') from myTable;
2019-10-07 12:00:00.000000

但是,就像我说的那样,我不想对此进行硬编码(因为其他数据库在其他TZ运行),而Postgres知道它是自己的时区。

还有其他语法可以正确执行此操作吗?

postgresql nestjs typeorm
3个回答
0
投票

无论服务器配置如何,Postgres中的所有时间戳都存储在UTC中。这一点很重要,要意识到,与其他数据库不同,它不会将您的输入解释为在其本地时区。但是,它将在其时区显示它。

timestamp仅存储没有时区的时间。 timestamp存储UTC以及时区。

在时区设置为UTC的Postgres服务器上一起演示这些内容

=> create table demo ( time timestamp, timetz timestamptz );
CREATE TABLE

=> insert into demo values ('2019-10-07 10:00', '2019-10-07 12:00 +0200');
INSERT 0 1

=> select * from demo;
        time         |         timetz         
---------------------+------------------------
 2019-10-07 10:00:00 | 2019-10-07 10:00:00+00

timestamp忽略偏移量,仅存储2019年10月7日10:00且没有偏移量。尽管timestamptz存储的偏移量为+0200,但会以其自己的UTC时区向我显示时间。他们是同一时间点。


您可以将会话的数据库时区更改为CEST。然后Postgres将在CEST中格式化timestamptz。

=> set time zone 'Antarctica/Troll';

=> select * from demo;
        time         |         timetz         
---------------------+------------------------
 2019-10-07 10:00:00 | 2019-10-07 12:00:00+02

但是这很脆弱。您必须确保它在每个连接上都发生。您的应用程序依赖于数据库连接的特定配置。这是action-at-a-distance anti-pattern。格式化的方式尚不明确,如果将其删除,很多看似无关的东西就会中断。

相反,从数据库收到时间后,您应该根据自己的意愿重新设置时间。您可以手动执行此操作...

=> select timetz at time zone 'CEST' from demo;
      timezone       
---------------------
 2019-10-07 12:00:00

但是通常,这是您的ORM会为您处理的事情。我不知道typeorm,但是大多数人都有一种一致地翻译数据库类型的方法。您应该可以将typeorm设置为自动将Postgres时间戳转换为本地应用程序时区。更好的是,与其返回字符串,不如将其转换为适当的Time对象,然后您就可以完全控制它了。


0
投票

选择时区'utc'时区'america / los_angeles'的created_at来自用户;


0
投票

从测试中选择ts_tz AT TIME ZONE'UTC;

© www.soinside.com 2019 - 2024. All rights reserved.