postgresql - postgresql - 为什么 now() 保存后不正确?
问题描述
所以就像这样,我有一个这样的程序:
CREATE OR REPLACE PROCEDURE public.savetrbankd(
_transcode text,
_id integer,
_expensecode text,
_debetamt numeric,
_creditamt numeric)
LANGUAGE 'plpgsql'
AS $BODY$
Declare
BEGIN
If _id=0 Then
INSERT INTO trbankd(transcode,expensecode,ket,debetamt,creditamt)
VALUES(_transcode,_expensecode,_ket,_debetamt,_creditamt);
Else
UPDATE trbankd SET
expensecode=_expensecode,
debetamt=_debetamt,
creditamt=_creditamt,
LastUpdatedDate=now()
WHERE transcode=_transcode and id=_id;
END IF;
END;
$BODY$;
让我们注意这里的“lastupdateddate”字段。类型为不带时区的timestamp,默认值为now()。
因此,在使用此过程插入/更新记录后,我尝试再次查询数据。所以我得到了:2021-07-23 23:48:42.805869
但是当我插入/更新记录时,应该是 2021 年 7 月 24 日下午 1 点左右。所以我们在 13-14 小时内得到了不同的时区?
当然,然后当我尝试显示时区时,它说是我们/太平洋。然后我将时区设置为 asia/bangkok(这是我的真实时区),代码如下:set timezone='Asia/Bangkok'。数据没有改变。它仍然说 lastupdateddate 是 2021 年 7 月 23 日。好吧,也许之前输入的数据不会改变,因为我使用了没有时区类型的时间戳。所以我尝试使用存储过程再次更新数据,它仍然显示 2021-07-24 00:29:23.384443 <= 注意,我浪费了一些时间试图找出时区,所以当我第二次更新时到这里的时间,已经是1小时左右,而我的实际时间是下午2点左右。
所以它仍然是大约 13-14 小时的相同差异。我如何确保插入和查询的数据与服务器(恰好是我的计算机)相同。作为补充说明,我的设置控制面板区域是我们(英语),我的位置已设置为印度尼西亚(gmt +7),并且我当前在计算机上的时间是正确的(就像我在上面所说的那样是下午 1-2 点)。
提前谢谢
解决方案
您发现将时间戳数据存储在timestamp without time zone
字段中通常不是一个好主意,尤其是在跨时区工作时。有关timestamp without time zone
(timestamp) 和timestamp with time zone
(timestamptz) 如何使用时间戳的详细信息,请参见此处:
https://www.postgresql.org/docs/current/datatype-datetime.html
8.5.1.3。时间戳
为了说明您所看到的:
select '2021-07-23 23:48:42.805869'::timestamp AT time zone 'US/Pacific';
timezone
-------------------------------
2021-07-23 23:48:42.805869-07
select '2021-07-23 23:48:42.805869'::timestamp AT time zone 'US/Pacific' AT time zone 'Asia/Bangkok';
timezone
----------------------------
2021-07-24 13:48:42.805869
---Current time here(I'm in 'US/Pacific')
test(5432)=# show timezone;
TimeZone
------------
US/Pacific
(1 row)
test(5432)=# select now()::timestamp;
now
----------------------------
2021-07-24 08:57:07.780014
test(5432)=# set timezone = 'Asia/Bangkok';
SET
test(5432)=# select now()::timestamp;
now
----------------------------
2021-07-24 22:56:14.659657
now()
正在获取服务器中设置的时区(或通过客户端重置)并使用它来创建时间戳。由于它被存储到timestamp
没有时区偏移量。您处理此问题的选择是:
保持原样,
timestamp without time zone
字段和timezone='US/Pacific'
. 根据需要翻译到本地时区。将字段转换为
timestamp with time zone
. 不过,在您执行此操作之前,您需要确定您知道当前值实际代表什么。
推荐阅读
- delphi - 如何为 onclick 事件选择 Delphi 框架而不是其组件?
- c# - 获取特定应用程序 C# 的 PID
- api - 如何使用颤振将地图的地图迭代到小部件?
- react-native - [未处理的承诺拒绝:错误:预期的 URL 方案“http”或“https”但是“文件”]
- python - 将 Python .exe 文件发送到没有 Python 的机器
- php - 如何在php中的数组中设置逗号?
- react-native - 当模态在本机中打开时,我如何单击模态后面的组件
- visual-studio-2015 - SSIS 约束
- autodesk-forge - 在伪造查看器上加载和运行扩展
- ruby-on-rails - Rails ActiveRecord - 字段验证