我尝试在主机上使用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 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
因此,我希望将其轻松转换为我要求的格式很容易。但是,我发现以下示例似乎无效:
> 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知道这是自己的时区。
还有另一种语法可以正确执行此操作吗?
答案 0 :(得分:2)
无论服务器配置如何,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对象,然后您可以完全控制它。
答案 1 :(得分:-1)
在时区“ utc”处选择“ created_at”,在时区“ america / los_angeles” 来自用户;
答案 2 :(得分:-1)
从测试中选择ts_tz AT TIME ZONE'UTC';