以格林威治标准时间生成日期的所有分钟并获取其本地值
generate all minute of a date in gmt and get their local value
我开始相信我所追求的对于 postgresql 来说是不可能的:
我想要给定日期的每个格林威治标准时间的分钟,并在与 timestamp without time zone
相同的 table 中也获取他们的本地版本。
到目前为止,我能够得到 GMT 和一些完全错误的偏移量。 (我无法更改 SET TIME ZONE 'Europe/Paris'
每次我尝试注入时区时都会输入 +1h
)
CREATE TABLE to_do ("id" int, "tz_lib" varchar(16));
CREATE TABLE date_needed ("date_lib" date);
查询 3:
insert into t1(id,tz_lib,date_gmt, date_local)
select
id,
tz_lib,
date_lib + (seq ||'minute')::interval AS date_gmt,
(date_lib + (seq ||'minute')::interval) at time zone tz_lib AS date_local
from date_needed
cross join to_do
cross join generate_series(0,1439) AS seq
| id | tz_lib | date_gmt | date_local |
|----|------------------|----------------------|----------------------|
| 1 | Pacific/Auckland | 2018-01-15T00:00:00Z | 2018-01-14T12:00:00Z |
| 2 | Europe/Paris | 2018-01-15T00:00:00Z | 2018-01-15T00:00:00Z |
| 3 | Asia/Hong_Kong | 2018-01-15T00:00:00Z | 2018-01-14T17:00:00Z |
| 1 | Pacific/Auckland | 2018-01-15T00:01:00Z | 2018-01-14T12:01:00Z |
| 2 | Europe/Paris | 2018-01-15T00:01:00Z | 2018-01-15T00:01:00Z |
| 3 | Asia/Hong_Kong | 2018-01-15T00:01:00Z | 2018-01-14T17:01:00Z |
| 1 | Pacific/Auckland | 2018-01-15T00:02:00Z | 2018-01-14T12:02:00Z |
| 2 | Europe/Paris | 2018-01-15T00:02:00Z | 2018-01-15T00:02:00Z |
| 3 | Asia/Hong_Kong | 2018-01-15T00:02:00Z | 2018-01-14T17:02:00Z |
| 1 | Pacific/Auckland | 2018-01-15T00:03:00Z | 2018-01-14T12:03:00Z |
小心使用 INTERVAL
的答案,因为他们不知道夏令时,并且在半年内都会出错(遗憾的是......)
好结果,坏方法:
目前我发现获得异常结果的唯一方法是将服务器时区更改为 GMT 并强制转换 date_local :
但是我不能对我的情况使用这个解决方案...
查询 1:
SET TIME ZONE 'GMT'
insert into t1(id,tz_lib,date_gmt, date_local)
select
id,
tz_lib,
date_lib + (seq ||'minute')::interval AS date_gmt,
(date_lib + (seq ||'minute')::interval)::timestamptz at time zone tz_lib AS date_local
from date_needed
cross join to_do
cross join generate_series(0,1439) AS seq
结果(和预期结果):
| id | tz_lib | date_gmt | date_local |
|----|------------------|----------------------|----------------------|
| 1 | Pacific/Auckland | 2018-01-15T00:00:00Z | 2018-01-15T13:00:00Z |
| 2 | Europe/Paris | 2018-01-15T00:00:00Z | 2018-01-15T01:00:00Z |
| 3 | Asia/Hong_Kong | 2018-01-15T00:00:00Z | 2018-01-15T08:00:00Z |
| 1 | Pacific/Auckland | 2018-01-15T00:01:00Z | 2018-01-15T13:01:00Z |
| 2 | Europe/Paris | 2018-01-15T00:01:00Z | 2018-01-15T01:01:00Z |
| 3 | Asia/Hong_Kong | 2018-01-15T00:01:00Z | 2018-01-15T08:01:00Z |
| 1 | Pacific/Auckland | 2018-01-15T00:02:00Z | 2018-01-15T13:02:00Z |
| 2 | Europe/Paris | 2018-01-15T00:02:00Z | 2018-01-15T01:02:00Z |
| 3 | Asia/Hong_Kong | 2018-01-15T00:02:00Z | 2018-01-15T08:02:00Z |
| 1 | Pacific/Auckland | 2018-01-15T00:03:00Z | 2018-01-15T13:03:00Z |
我认为解决方案是始终使用 timestamp without time zone
:
SELECT to_do.id,
to_do.tz_lib,
seq.seq AS date_gmt,
seq.seq AT TIME ZONE 'UTC' AT TIME ZONE to_do.tz_lib AS date_local
FROM to_do
CROSS JOIN date_needed
CROSS JOIN LATERAL
generate_series(
date_needed.date_lib::timestamp,
date_needed.date_lib::timestamp + INTERVAL '1439 minutes',
INTERVAL '1 minute'
) seq;
说明:seq
将传送 UTC 时间戳。通过使用 AT TIME ZONE 'UTC'
,我将它正确地转换为 timestamp with time zone
,而第二个 AT TIME ZONE
我看到了当时那个时区的时钟显示的内容。
我开始相信我所追求的对于 postgresql 来说是不可能的:
我想要给定日期的每个格林威治标准时间的分钟,并在与 timestamp without time zone
相同的 table 中也获取他们的本地版本。
到目前为止,我能够得到 GMT 和一些完全错误的偏移量。 (我无法更改 SET TIME ZONE 'Europe/Paris'
每次我尝试注入时区时都会输入 +1h
)
CREATE TABLE to_do ("id" int, "tz_lib" varchar(16));
CREATE TABLE date_needed ("date_lib" date);
查询 3:
insert into t1(id,tz_lib,date_gmt, date_local)
select
id,
tz_lib,
date_lib + (seq ||'minute')::interval AS date_gmt,
(date_lib + (seq ||'minute')::interval) at time zone tz_lib AS date_local
from date_needed
cross join to_do
cross join generate_series(0,1439) AS seq
| id | tz_lib | date_gmt | date_local |
|----|------------------|----------------------|----------------------|
| 1 | Pacific/Auckland | 2018-01-15T00:00:00Z | 2018-01-14T12:00:00Z |
| 2 | Europe/Paris | 2018-01-15T00:00:00Z | 2018-01-15T00:00:00Z |
| 3 | Asia/Hong_Kong | 2018-01-15T00:00:00Z | 2018-01-14T17:00:00Z |
| 1 | Pacific/Auckland | 2018-01-15T00:01:00Z | 2018-01-14T12:01:00Z |
| 2 | Europe/Paris | 2018-01-15T00:01:00Z | 2018-01-15T00:01:00Z |
| 3 | Asia/Hong_Kong | 2018-01-15T00:01:00Z | 2018-01-14T17:01:00Z |
| 1 | Pacific/Auckland | 2018-01-15T00:02:00Z | 2018-01-14T12:02:00Z |
| 2 | Europe/Paris | 2018-01-15T00:02:00Z | 2018-01-15T00:02:00Z |
| 3 | Asia/Hong_Kong | 2018-01-15T00:02:00Z | 2018-01-14T17:02:00Z |
| 1 | Pacific/Auckland | 2018-01-15T00:03:00Z | 2018-01-14T12:03:00Z |
小心使用 INTERVAL
的答案,因为他们不知道夏令时,并且在半年内都会出错(遗憾的是......)
好结果,坏方法:
目前我发现获得异常结果的唯一方法是将服务器时区更改为 GMT 并强制转换 date_local :
但是我不能对我的情况使用这个解决方案...
查询 1:
SET TIME ZONE 'GMT'
insert into t1(id,tz_lib,date_gmt, date_local)
select
id,
tz_lib,
date_lib + (seq ||'minute')::interval AS date_gmt,
(date_lib + (seq ||'minute')::interval)::timestamptz at time zone tz_lib AS date_local
from date_needed
cross join to_do
cross join generate_series(0,1439) AS seq
结果(和预期结果):
| id | tz_lib | date_gmt | date_local |
|----|------------------|----------------------|----------------------|
| 1 | Pacific/Auckland | 2018-01-15T00:00:00Z | 2018-01-15T13:00:00Z |
| 2 | Europe/Paris | 2018-01-15T00:00:00Z | 2018-01-15T01:00:00Z |
| 3 | Asia/Hong_Kong | 2018-01-15T00:00:00Z | 2018-01-15T08:00:00Z |
| 1 | Pacific/Auckland | 2018-01-15T00:01:00Z | 2018-01-15T13:01:00Z |
| 2 | Europe/Paris | 2018-01-15T00:01:00Z | 2018-01-15T01:01:00Z |
| 3 | Asia/Hong_Kong | 2018-01-15T00:01:00Z | 2018-01-15T08:01:00Z |
| 1 | Pacific/Auckland | 2018-01-15T00:02:00Z | 2018-01-15T13:02:00Z |
| 2 | Europe/Paris | 2018-01-15T00:02:00Z | 2018-01-15T01:02:00Z |
| 3 | Asia/Hong_Kong | 2018-01-15T00:02:00Z | 2018-01-15T08:02:00Z |
| 1 | Pacific/Auckland | 2018-01-15T00:03:00Z | 2018-01-15T13:03:00Z |
我认为解决方案是始终使用 timestamp without time zone
:
SELECT to_do.id,
to_do.tz_lib,
seq.seq AS date_gmt,
seq.seq AT TIME ZONE 'UTC' AT TIME ZONE to_do.tz_lib AS date_local
FROM to_do
CROSS JOIN date_needed
CROSS JOIN LATERAL
generate_series(
date_needed.date_lib::timestamp,
date_needed.date_lib::timestamp + INTERVAL '1439 minutes',
INTERVAL '1 minute'
) seq;
说明:seq
将传送 UTC 时间戳。通过使用 AT TIME ZONE 'UTC'
,我将它正确地转换为 timestamp with time zone
,而第二个 AT TIME ZONE
我看到了当时那个时区的时钟显示的内容。