GPX 和 PostgreSQL 的夏令时

Daylight savings time for GPX and PostgreSQL

所以我在这里使用 gpx 文件。请注意其中的摘录:

<?xml version="1.0" encoding="UTF-8"?>
<!-- GPSTrack 2.2.1 — http://bafford.com/gpstrack -->
<gpx xmlns="http://www.topografix.com/GPX/1/1">
<trk>
<name><![CDATA[2016-03-31 10-17-54]]></name>
<trkseg>
<trkpt lat="38.704859" lon="-8.970304"><ele>13.050667</ele><time>2016-03-31T09:17:51Z</time><!-- hAcc=95.768176 vAcc=10.000000 --></trkpt>
<trkpt lat="38.704894" lon="-8.970324"><ele>13.050667</ele><time>2016-03-31T09:17:55Z</time><!-- hAcc=141.087476 vAcc=10.000000 --></trkpt>
<trkpt lat="38.704859" lon="-8.970304"><ele>13.050667</ele><time>2016-03-31T09:17:55Z</time><!-- hAcc=95.768176 vAcc=10.000000 --></trkpt>
<trkpt lat="38.704878" lon="-8.970343"><ele>13.150488</ele><time>2016-03-31T09:18:43Z</time><!-- hAcc=165.000000 vAcc=10.000000 --></trkpt>

看到文件名了吗?它给了我们时间 10H17。现在检查每个点的时间。少一小时算。

我还是不明白这里的时代是怎么一团糟的。但这才是问题的开始。

现在,我正在解析这么多 gpx 文件,并将它们加载到 PostgreSQL 数据库中。更具体地说,这个 table:

CREATE TABLE IF NOT EXISTS trips (
  trip_id SERIAL PRIMARY KEY,

  start_location TEXT REFERENCES locations(label),
  end_location TEXT REFERENCES locations(label),

  start_date TIMESTAMP WITHOUT TIME ZONE NOT NULL,
  end_date TIMESTAMP WITHOUT TIME ZONE NOT NULL,

  bounds geography(POLYGONZ, 4326) NOT NULL,
  points geography(LINESTRINGZ, 4326) NOT NULL,

  timestamps TIMESTAMP WITHOUT TIME ZONE[] NULL
);

即使在使用 TIMESTAMP WITHOUT TIME ZONE 时,点加载的时间也有误(少了一小时)。这仅发生在夏令时生效后的几天。这里的要点是:有什么方法可以检查日期是否在夏令时时间,如果检查到,则增加一小时?

我检查了 tm_isdstdatetime.dst() 但我还是不明白。

如果您知道时区名称,这个当地时间应该是设置(假设示例中为 'Europe/Vienna'),您可以将值归一化以更正 UTC 时间(或 any 其他时区)用这个表达式:

SELECT '2016-03-31T09:17:51Z'::timestamp AT TIME ZONE 'Europe/Vienna' AT TIME ZONE 'UTC'

结果:

timezone
--------------------
2016-03-31 07:17:51

是,申请AT ZIME ZONE两次

由于您似乎要处理不同的时区,我会考虑在您的表格中使用 timestamptz 而不是 timestamp

请务必使用时区 名称,而不是缩写或简单的时间偏移量以获得 DST 的精确调整。
我讨厌 "daylight saving time" 的愚蠢概念 - 它永远不会节省任何日光,而是不断浪费人们被它迷惑的宝贵时间。

所有这些的详细解释:

  • Ignoring timezones altogether in Rails and PostgreSQL

  • How to get a time zone from a location using latitude and longitude coordinates?