2016-07-31 50 views
0

所以我在这里使用gpx文件。注意一个选段:GPX和PostgreSQL的夏令时

<?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数据库中。更具体地说,本表:

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点被加载有错误的小时(小于一小时)。这只发生在夏令时生效后的几天内。这里的观点:有没有办法检查日期是否在DST时间,并且如果检查时加上一个小时?

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

回答

0

如果您知道其中该本地时间应该在(假设在例如“欧洲/维也纳”)要设置的时区名称,您可以正常化值纠正UTC时间(或任何其他时区)这个表达式:

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。
我讨厌夏令时的概念 - 它从不保存任何日光,但不断浪费人们被它迷惑的宝贵时间。

对所有这一切详细解释:

+0

不错,虽然我对DST同意你浪费了我们的时间,它肯定是好的,在夏天哈哈还有一个小时的阳光。 所以,关于我的问题,我理解你的答案,并且我改变了我的表格,使'TIMESTAMP WITH TIME ZONE'。虽然日期是在同一个国家收集的,但是这个DST内容被视为一个时区。 使用'pgAdmin'工具我现在看到我的表格显示了这样的日期: '2016-03-31 09:17:51 + 01'。这意味着当我查询日期并将其传递给我想要的任何函数时,它会认为它是10:17,对吧? –

+0

@ Shoplifter.Doe:[正如链接的答案中所解释的](*解释*)(* http://stackoverflow.com/questions/9571392/ignoring-timezones-altogether-in-rails-and-postgresql/9576170#9576170),*显示* 'timestamptz'适用于会话的时区设置。您可以再一次使用AT TIME ZONE构造获得给定时区的显示。当*将*转换为'日期'时,也会考虑当前的时区设置。 –

+0

是的,我知道了。会话的时区设置绰绰有余。 “夏令时并不是人类有史以来最明智的想法之一。” - 编程问题确实如此。 对于我来说,'SELECT start_date :: timestamp AT TIME ZONE'UTC'from trips'表达式是适用于我的那个。就像你的链接答案中的“加载的弩枪”一样。 在我的前端,我可以用一些JS库轻松处理这些日期。 我很不知道这些时区可能是一个痛苦。感谢您的教训。 –