我正在将基于Web的前端编写到数据库(PHP / Postgresql)中,我需要在其中存储各种日期/时间.该时间应始终在本地时间在客户端输入,并也在本地时间显示.出于存储目的,我将所有日期/时间存储为整数(UNIX时间戳)并标准化为UTC.一个特定的字段有一个限制,即将来不允许填写时间戳,因此我尝试了数据库约束…
CONSTRAINT not_future
CHECK (timestamp-300 <= date_part('epoch', Now() at time zone 'UTC'))
如果浏览器和服务器之间的时间稍微不同步,则-300将有5分钟的余地.
问题是,提交当前时间时,此约束始终失败.我已经完成测试,发现以下内容.
在Postgresql客户端中:
SELECT Now()-返回正确的本地时间
SELECT date_part(‘epoch’,Now())-返回UTC的unix时间戳(通过将值输入到PHP中的date函数中以对其对我的时区的补偿进行校正来进行测试)
SELECT date_part(‘epoch’,Now()at time zone’UTC’)-返回以两个时区向西偏移的unix时间戳,例如我在格林尼治标准时间2,得到GMT-2时间戳.
我已经清楚地知道,删除“在时区’UTC’”会解决我的问题,但是我的问题是,“ epoch”是否旨在返回AFAIK始终位于UTC的unix时间戳,为什么? UTC中已经存在的“时代”会被纠正吗?这是一个错误,还是我在这里缺少有关已定义/正常行为的信息.
解决方法:
“时区’UTC’的Now()”值是您当前的时间,该时间已移至UTC,然后转换为TIMESTAMP WITHOUT TIME ZONE.
因此,您给“ date_part”一个没有时区的TIMESTAMP(换句话说,未知时区),并期望在已知时区收到它与固定时间戳之间的秒差(“ EPOCH”,1970-01-01 00: 00:00 UTC).
Postgres需要TIMESTAMP WITH TIME ZONE进行计算.因此,它将您的值转换为时区’UTC’assuming it’s at your time zone并计算差值.
就像是:
select ((Now() at time zone 'UTC') at time zone '<your_time_zone>') at time zone 'UTC';