Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
仅在UTC 2:00时检索时间戳(带时区)行的SQL查询,而不考虑夏令时_Sql_Postgresql - Fatal编程技术网

仅在UTC 2:00时检索时间戳(带时区)行的SQL查询,而不考虑夏令时

仅在UTC 2:00时检索时间戳(带时区)行的SQL查询,而不考虑夏令时,sql,postgresql,Sql,Postgresql,我相信这个标题可能会让人困惑。在标题中找不到这样一个好的词而不把它写得很长 简言之 我有一个PSQL数据库表,它每15分钟归档一个外部API端点。该表包含以下列: id(序列号) 匹配(jsonb) 快照时间(时区为not null的时间戳默认值现在为() 我需要一个SQL查询,该查询将仅获取以下约束下的行: 这一天必须是星期六(6) 时间戳必须位于ISO8601的“…T02:00:00Z” 在指定的开始日期和结束日期之间 我目前拥有的 SELECT id,snapshot_time,m

我相信这个标题可能会让人困惑。在标题中找不到这样一个好的词而不把它写得很长

简言之

我有一个PSQL数据库表,它每15分钟归档一个外部API端点。该表包含以下列:

  • id(序列号)
  • 匹配(jsonb)
  • 快照时间(时区为not null的时间戳默认值现在为()
我需要一个SQL查询,该查询将仅获取以下约束下的行:

  • 这一天必须是星期六(6)
  • 时间戳必须位于ISO8601的“…T02:00:00Z”
  • 在指定的开始日期和结束日期之间
我目前拥有的

SELECT id,snapshot_time,match->'kills' FROM match_archive 
WHERE extract(dow from snapshot_time)=6 
AND snapshot_time >= '2016-12-01' 
AND date_part('hour', snapshot_time)=2 
AND date_part('minute', snapshot_time)=00;
(例如,开始和结束时间当前是硬编码的)

问题

这将返回正确的行,但问题是,由于
快照_time
列是带时区的
时间戳类型,因此产生的行实际上与我居住在东部标准时间间隔5小时

它返回的一个示例行是

   id   |         snapshot_time         |                  ?column?
--------+-------------------------------+--------------------------------------------
 120941 | 2016-12-03 02:00:03.32946-05  | {"red": 3389, "blue": 1962, "green": 2911}
如您所见,快照时间确实是2:00,但它是在美国东部时间

我想,“嘿,我可以把时间定在21小时,一周中的第五天(星期五)”,这样就行了,但突然之间,由于未来的夏令时,时间会缩短一个小时

另一件事是使用不带时区的
时间戳存储信息
,但随后发生的事情是将
2016-12-03T17:44:21-05
切掉
-05
,并在数据库中插入新行时将其保留为
2016-12-03T17:44:21Z

那么,有没有什么好方法可以创建一个SQL查询,使我能够按照上面列出的要求获取行,而不必担心夏令时?谢谢

这将返回正确的行,但问题是,由于snapshot_time列的类型为timestamp with time zone,因此产生的行实际上与我居住在东部标准时间间隔5小时

时间戳始终以UTC格式存储在PostgreSQL中

对于带有时区的时间戳,内部存储的值始终以UTC(通用协调时间,传统上称为格林威治标准时间,GMT)为单位。指定了明确时区的输入值将使用该时区的适当偏移量转换为UTC。如果输入字符串中未说明时区,则假定它位于系统时区参数指示的时区中,并使用时区的偏移量转换为UTC

当输出带有时区值的时间戳时,它总是从UTC转换为当前时区,并在该时区中显示为本地时间。要查看另一时区中的时间,请更改时区或使用AT时区结构(请参阅)

这将返回正确的行,但问题是,由于snapshot_time列的类型为timestamp with time zone,因此产生的行实际上与我居住在东部标准时间间隔5小时

时间戳始终以UTC格式存储在PostgreSQL中

对于带有时区的时间戳,内部存储的值始终以UTC(通用协调时间,传统上称为格林威治标准时间,GMT)为单位。指定了明确时区的输入值将使用该时区的适当偏移量转换为UTC。如果输入字符串中未说明时区,则假定它位于系统时区参数指示的时区中,并使用时区的偏移量转换为UTC

当输出带有时区值的时间戳时,它总是从UTC转换为当前时区,并在该时区中显示为本地时间。要查看另一时区中的时间,请更改时区或使用AT时区结构(请参阅)


如果有人在谷歌上遇到这个问题,请回答我的问题

根据Evan Carroll的回答,以下SQL解决了我的问题:

SELECT id,snapshot_time,match->'kills' FROM match_archive 
WHERE extract(dow from snapshot_time AT TIME ZONE 'UTC')=5 
AND snapshot_time >= '2016-12-01' 
AND date_part('hour', snapshot_time AT TIME ZONE 'UTC')=2 
AND date_part('minute', snapshot_time AT TIME ZONE 'UTC')=00;

可能在分钟日期部分没有必要,但要保持一致。

回答我的问题,以防有人在谷歌上遇到这个问题

根据Evan Carroll的回答,以下SQL解决了我的问题:

SELECT id,snapshot_time,match->'kills' FROM match_archive 
WHERE extract(dow from snapshot_time AT TIME ZONE 'UTC')=5 
AND snapshot_time >= '2016-12-01' 
AND date_part('hour', snapshot_time AT TIME ZONE 'UTC')=2 
AND date_part('minute', snapshot_time AT TIME ZONE 'UTC')=00;

分钟日期部分可能不需要,但希望保持一致。

虽然我知道您可能没有此选项,但请理解,最佳做法是首先始终以UTC格式存储日期时间数据。如果这样做了,这个问题就不会出现。即使是现在,如果我有选择的话,我也会认真研究将数据库中所有现有的本地时区日期时间数据(以及驱动它的代码)转换为UTC。@CharlesBretana在PostgreSQL中存储UTC时区甚至不是一个选择。这就是它们的存储方式。我没有说存储时区,而是说存储UTC的日期时间。不过,我承认我不熟悉PostgreSQL。您是说您无法控制存储在PostGreSQL表的datetime列中的值吗?客户端软件不能存储UTC值而不是本地时间值?不。我是说您只能存储UTC。虽然我知道您可能没有此选项,但请理解,最佳做法是首先始终以UTC存储日期时间数据。如果这样做了,这个问题就不会出现。即使是现在,如果我有选择的话,我也会认真研究将数据库中所有现有的本地时区日期时间数据(以及驱动它的代码)转换为UTC。@CharlesBretana在PostgreSQL中存储UTC时区甚至不是一个选择。这就是它们的存储方式。我没有说存储时区,而是说存储UTC的日期时间。不过,我承认我不熟悉PostgreSQL。你是说你不能控制你存储在datetime列中的值吗