2016-07-31 33 views
0

Also hier arbeite ich mit GPX-Dateien. Beachten Sie einen Auszug aus einem:Sommerzeit für GPX und 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> 

Siehe den Namen der Datei? Es gibt uns die Zeit 10H17. Überprüfen Sie jetzt die Zeit für jeden Punkt. Es wird mit einer Stunde weniger gezählt.

Ich verstehe immer noch nicht, wie die Zeiten hier versaut sind. Aber das ist der Anfang des Problems.

Jetzt analysiere ich diese vielen GPX-Dateien und lade sie in eine PostgreSQL-Datenbank. Insbesondere diese Tabelle:

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 
); 

Auch während TIMESTAMP WITHOUT TIME ZONE die Punkte mit der falschen Stunde geladen (eine weniger Stunden) werden. Dies geschieht nur in den Tagen nach der Sommerzeit. Der Punkt hier: Gibt es eine Möglichkeit zu überprüfen, ob ein Datum in der Sommerzeit ist und eine Stunde hinzufügen, wenn das überprüft?

Ich überprüft für tm_isdst und datetime.dst(), aber ich verstehe es immer noch nicht.

Antwort

0

Wenn Sie der Zeitzone Name wo diese lokale Zeit sollte wissen gesetzt wird in (unter der Annahme ‚Europe/Vienna‘ im Beispiel), können Sie den Wert normalisieren UTC-Zeit zu korrigieren (oder jede andere Zeitzone) mit diesem Ausdruck:

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

Ergebnis:

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

Ja, anwenden AT ZIME ZONEzweimal.

Da Sie scheinen sich mit verschiedenen Zeitzonen zu beschäftigen, würde ich timestamptz anstelle von timestamp in Ihren Tabellen verwenden.

Seien Sie sicher, dass die Zeitzone Namen, keine Abkürzungen oder Normalzeit-Offsets zu erhalten präzise Einstellungen für DST verwenden.
Ich hasse das schwachsinnige Konzept der "Sommerzeit" - es spart nie Tageslicht, aber verschwendet wertvolle Zeit der Menschen durch sie verwirrt werden.

Ausführliche Erklärung für all das:

+0

gut, obwohl ich mit Ihnen auf DST verschwenden wir Zeit zustimmen, es ist sicher schön, noch eine Stunde Sonne im Sommer haha. Also, in Bezug auf mein Problem, habe ich Ihre Antwort verstanden, und ich änderte meine Tabelle, um 'TIMESTAMP MIT ZEITZONE 'zu haben. Obwohl das Datum in demselben Land erfasst wird, wird diese DST-Bohrung als Zeitzone verwendet. Mit dem 'pgAdmin' Werkzeug sehe ich jetzt, dass meine Tabelle das Datum wie folgt zeigt ' 2016-03-31 09: 17: 51 + 01'. Das bedeutet, wenn ich nach dem Datum frage und es an die von mir gewünschte Funktion weitergebe, wird es als 10:17 gelten, oder? –

+0

@ Shoplifter.Doe: [Wie in der verknüpften Antwort erklärt] (http://stackoverflow.com/questions/9571392/ignoring-timezones-algether-in-rails-and-postgresql/9576170#9576170), die * Anzeige * von 'Zeitstempel' ist an die Zeitzoneneinstellung der Sitzung angepasst. Sie können das Konstrukt "AT TIME ZONE" immer wieder verwenden, um die Anzeige für eine bestimmte Zeitzone zu erhalten. Wenn Sie * auf * Datum * umstellen, wird auch die aktuelle Zeitzoneneinstellung berücksichtigt. –

+0

Ja, ich habe es verstanden. Die Zeitzoneneinstellung der Sitzung ist mehr als genug. "Die Sommerzeit gehört nicht zu den hellsten Ideen, die die Menschheit jemals entwickelt hat." - Bei Programmierungsproblemen ist dies in der Tat der Fall. Für mich ist der 'SELECT start_date :: timestamp AT TIME ZONE' UTC 'von trips' Ausdruck, der für mich funktioniert. Ähnlich wie Ihre "geladene Fußfeuerwaffe" aus der verknüpften Antwort. In meinem Front-End kann ich mit diesen Daten problemlos mit einigen JS-Bibliotheken umgehen. Ich war weit davon entfernt zu wissen, dass diese Zeitzonen ein Schmerz sein können. Danke für die Lektion. –