[英]PostgreSQL: Compute number of hours in the day on daylight savings time
I'm trying to come up with a query that will properly count that there are 25 hours on daylight savings. 我正在尝试提出一个查询,该查询将正确地计算出有25个小时的夏时制。 My table has a column of type timestampz called hourly_timestamp. 我的表具有一列名为timely_timestamp的timestampz类型的列。 The incorrect answer I have so far looks like this: 到目前为止,我得到的错误答案如下所示:
select EXTRACT(epoch FROM tomorrow-today)/3600
from(
select date_trunc('day', timezone('America/New_York', hourly_timestamp) as today ,
date_trunc('day', timezone('America/New_York', hourly_timestamp)))
+ '1 day'::interval as tomorrow
)t;
When this query executed during daylight savings time, I still only get 24 hours back and not 25. Any ideas how to do this correctly? 在夏令时期间执行此查询时,我仍然只能得到24小时,而不是25小时。有什么主意如何正确执行此操作?
You first have to do the extraction to epoch and then the calculations: 您首先必须提取到纪元,然后进行计算:
WITH test AS (
SELECT '2014-10-26'::timestamptz at time zone 'America/New_York' AS today,
'2014-10-27'::timestamptz at time zone 'America/New_York' AS tomorrow
)
SELECT
extract(epoch from tomorrow) - extract(epoch from today) AS seconds, -- 90000
(extract(epoch from tomorrow) - extract(epoch from today)) / 3600 AS hours -- 25
FROM test;
The number of hours varies with the clock. 小时数随时钟而变化。
with hours as (
select (timestamp with time zone '2014-11-01 00:00:00 America/New_York' + (n || ' hour')::interval) as hourly_timestamp
from generate_series(0, 72) n
)
select hourly_timestamp
, hourly_timestamp + interval '1' day as one_day_later
, hourly_timestamp + interval '1' day - hourly_timestamp as elapsed_time
from hours;
hourly_timestamp one_day_later elapsed_time -- [snip] 2014-11-01 22:00:00-04 2014-11-02 22:00:00-05 1 day 01:00:00 2014-11-01 23:00:00-04 2014-11-02 23:00:00-05 1 day 01:00:00 2014-11-02 00:00:00-04 2014-11-03 00:00:00-05 1 day 01:00:00 2014-11-02 01:00:00-04 2014-11-03 01:00:00-05 1 day 01:00:00 2014-11-02 01:00:00-05 2014-11-03 01:00:00-05 1 day 2014-11-02 02:00:00-05 2014-11-03 02:00:00-05 1 day 2014-11-02 03:00:00-05 2014-11-03 03:00:00-05 1 day 2014-11-02 04:00:00-05 2014-11-03 04:00:00-05 1 day [snip]
Note that 01:00 repeats, but with a different offset. 请注意,重复01:00,但偏移量不同。 Daylight savings time ends at 02:00, the clocks fall back and repeat the hour between 01:00 and 02:00, but since daylight savings time has ended, there are now five hours between the UTC and America/New_York time zones. 夏令时结束于02:00,时钟回退并在01:00到02:00之间重复一小时,但是由于夏令时结束,因此UTC与美国/纽约时区之间存在五个小时。
This similar query displays dates, not timestamps. 这个类似的查询显示日期,而不是时间戳。
with dates as (
select (timestamp with time zone '2014-11-01 00:00:00 America/New_York' + (n || ' day')::interval) as daily_timestamp
from generate_series(0, 2) n
)
select daily_timestamp::date
, (daily_timestamp + interval '1' day)::date as one_day_later
, daily_timestamp + interval '1' day - daily_timestamp as elapsed_time
from dates;
daily_timestamp one_day_later elapsed_time -- 2014-11-01 2014-11-02 1 day 2014-11-02 2014-11-03 1 day 01:00:00 2014-11-03 2014-11-04 1 day
Where did you go wrong? 你哪里出问题了? By calculating the elapsed time after you truncated the time information. 通过计算截断时间信息后经过的时间。 (Dates don't have time zones associated with them.) If I take the second query and cast "daily_timestamp" to a date in the common table expression, I get 24 hours, too. (日期没有与之关联的时区。)如果我进行第二个查询并将“ daily_timestamp”转换为公用表表达式中的日期,那么我也可以获得24小时。
with dates as (
select (timestamp with time zone '2014-11-01 00:00:00 America/New_York' + (n || ' day')::interval)::date as daily_timestamp
from generate_series(0, 2) n
)
select daily_timestamp::date
, (daily_timestamp + interval '1' day)::date as one_day_later
, daily_timestamp + interval '1' day - daily_timestamp as elapsed_time
from dates;
daily_timestamp one_day_later elapsed_time -- 2014-11-01 2014-11-02 1 day 2014-11-02 2014-11-03 1 day 2014-11-03 2014-11-04 1 day
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.