database - 夏令时期间的generate_series变化 - 根据服务器时区不同结果不同

标签 database postgresql timezone dst postgresql-9.6

当我的 postgres 服务器位于 America/New_York 时区,或者我使用SET SESSION TIME ZONE 'America/New_York'时,generate_series 会考虑夏令时的变化,我可以获得正确的纪元或点在我想要的时间:

postgres=# SET SESSION TIME ZONE 'America/New_York';
SET
postgres=#
postgres=# with seq(ts) as (select * from generate_series('2018-11-03 00:00:00.000 -04:00', '2018-11-06 13:40:39.067 -05:00', '1d'::interval))
postgres-# select ts, extract(epoch from ts) as epoch, ts at time zone 'America/New_York' as eastern
postgres-# from seq;
           ts           |   epoch    |       eastern
------------------------+------------+---------------------
 2018-11-03 00:00:00-04 | 1541217600 | 2018-11-03 00:00:00
 2018-11-04 00:00:00-04 | 1541304000 | 2018-11-04 00:00:00
 2018-11-05 00:00:00-05 | 1541394000 | 2018-11-05 00:00:00
 2018-11-06 00:00:00-05 | 1541480400 | 2018-11-06 00:00:00
(4 rows)

但是当我的服务器在生产环境中采用 UTC 时,generate_series 不考虑夏令时更改:

postgres=# SET SESSION TIME ZONE 'UTC';
SET
postgres=# with seq(ts) as (select * from generate_series('2018-11-03 00:00:00.000 -04:00', '2018-11-06 13:40:39.067 -05:00', '1d'::interval))
postgres-# select ts, extract(epoch from ts) as epoch, ts at time zone 'America/New_York' as eastern
postgres-# from seq;
           ts           |   epoch    |       eastern
------------------------+------------+---------------------
 2018-11-03 04:00:00+00 | 1541217600 | 2018-11-03 00:00:00
 2018-11-04 04:00:00+00 | 1541304000 | 2018-11-04 00:00:00
 2018-11-05 04:00:00+00 | 1541390400 | 2018-11-04 23:00:00
 2018-11-06 04:00:00+00 | 1541476800 | 2018-11-05 23:00:00
(4 rows)

通知 11/4 和 11/5 尚未针对 DST 更改进行调整。

有什么办法可以解决这个问题,而无需在查询时设置 session 时区吗?

使用 postgres 9.6...

最佳答案

session 时区控制如何解释 1 天的间隔,因此我认为您的问题的答案很简单:否。

Postgres docs解释如下:

When adding an interval value to (or subtracting an interval value from) a timestamp with time zone value, the days component advances or decrements the date of the timestamp with time zone by the indicated number of days. Across daylight saving time changes (when the session time zone is set to a time zone that recognizes DST), this means interval '1 day' does not necessarily equal interval '24 hours'. For example, with the session time zone set to CST7CDT, timestamp with time zone '2005-04-02 12:00-07' + interval '1 day' will produce timestamp with time zone '2005-04-03 12:00-06', while adding interval '24 hours' to the same initial timestamp with time zone produces timestamp with time zone '2005-04-03 13:00-06', as there is a change in daylight saving time at 2005-04-03 02:00 in time zone CST7CDT.

据我所知,除了将其设置为 session 时区之外,没有其他机制可以告诉在特定时区中解释的间隔。换句话说,我认为您会寻找类似 '1 day tz America/New_York'::interval 的内容,但我不相信存在这样的语法。

关于database - 夏令时期间的generate_series变化 - 根据服务器时区不同结果不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53270410/

相关文章:

SQL查询优化

python - Django 多数据库连接

java - 如何将 YYYY-MM-DDTHH :mm:ss. SSSZ 格式的时间转换为默认时区?

Laravel 根据偏好为用户更改时区

database - 具有租户之间公共(public)数据的 Multi-Tenancy 共享数据库

java - MongoDB 最佳实践——获取集合

node.js - Github 操作 - 未处理的拒绝 SequelizeConnectionError : no PostgreSQL user name specified in startup packet

sql - (Postgresql更新查询不返回

java - 及时为大量数据库请求配置Spring JPA和PostgreSQL

c# - 夏令时的灰色地带