2016-04-12 9 views
2

Follow-up-Frage zu meinem Original issue.Postgres UTC Java ZonedDateTime

Da ich weiß, dass jede verwendete Datumszeit für eine bekannte Zeitzone ist und nicht, wo der Benutzer seine Anfrage absetzt, nehme ich eine LocalDateTime, konvertiere nach UTC und bleibe bestehen. Dann, wenn der Termin abgerufen wird, konvertiere ich die gespeicherte Zeit in die Zeitzone des Besprechungsorts (gespeichert in db). Es scheint jedoch, dass die Werte, die ich speichere, tatsächlich in meiner lokalen Zeitzone gespeichert werden.

I erhalten ein Datum Zeitwert im Rest-Controller wie:

startLocalDateTime: 2016-04-11T10:00 
endLocalDateTime: 2016-04-11T10:30 

Termin hat zwei ZoneDateTime Felder:

@Column(name = "startDateTime", columnDefinition= "TIMESTAMP WITH TIME ZONE") 
private ZonedDateTime startDateTime; 
@Column(name = "endDateTime", columnDefinition= "TIMESTAMP WITH TIME ZONE") 
private ZonedDateTime endDateTime; 

Dann wechsle ich die Werte in UTC und speichern auf meiner Einheit speichern zu Postgres:

appointment.setStartDateTime(startLocalDateTime.atZone(ZoneId.of("UTC"))) 
appointment.setEndDateTime(endLocalDateTime.atZone(ZoneId.of("UTC"))) 

und ich speichern, dass in Postgres (columnDefinition= "TIMESTAMP WITH TIME ZONE") Wh en ich bei der Aufzeichnung in pgAdminIII aussehen sehe ich:

startDateTime "2016-04-11 04:00:00-06" 
endDateTime "2016-04-11 04:30:00-06" 

diese richtig im UTC-Format gespeichert werden, so erscheinen (bitte korrigieren Sie mich, wenn ich so viel falsch machen etwas tue). Ich sie dann aus der Datenbank abrufen und sie zurückgegeben werden, wie:

{ 
"appointmentId":50, 
"startDateTime":"2016-04-11T04:00", 
"endDateTime":"2016-04-11T04:30" 
} 

sogar So obwohl ich sie als UTC speichere, wenn ich sie sie abrufen:

Appointment 
startdatetime: 2016-04-11T04:00-06:00[America/Denver] 
enddatetime: 2016-04-11T04:30-06:00[America/Denver] 

Diese Werte zurück als JSON gesendet werden sind in MST (meiner lokalen) Zeitzone, anstatt UTC, und ich bin nicht in der Lage, sie zurück in die tatsächliche Zeit zu konvertieren.

Immer noch mit der Hartnäckigkeit zu kämpfen. Ich habe versucht, die java.sql.timestamp, java.sql.Date, java.util.Date und java.time.ZonedDateTime für meine Entität zu verwenden. Mein Postgres ist immer noch ein "Zeitstempel mit Zeitzone". Aber weil ich Spring-Data-JPA verwende und mit dem gleichen Typ abfragen muss. Wenn ich Date verwende - sollte das sql.Date oder util.Date sein?

+0

Sie werden immer noch in UTC gespeichert, da ein Java-Datum ** immer ** ** UTC ** ist (wenn es eine lokale Zeitzone enthält, wurde es formatiert). –

+0

Ich denke, ich verstehe nicht, warum die DB zeigt sie im UTC-Format und auch wenn sie als Teil eines Termins zurückgegeben wird, ist die Zeit UTC, aber die Zone scheint "Amerika/Denver" und nicht "UTC". Wie kann ich die korrekte Zeit zurückbekommen? – sonoerin

+0

Wie siehst du *** die Zeit? Weil Java "Date" als eine Anzahl von Millisekunden seit dem 1. Januar 1970 um Mitternacht UTC (aka EPOCH) speichert. –

Antwort

1

Der JDBC-Treiber hat etwas Wissen über die Zeitzone, in der Sie sich gerade befinden. Im Allgemeinen habe ich das in der Vergangenheit durch die Datenbank die Zeitzone Umwandlung für mich einige Ableitung von "Zeitstempel ohne Zeitzone AT TIME ZONE Zone "oder" Zeitstempel mit Zeitzone in der Zeitzone 'UTC' ". Es ist in den Eingeweiden des postgres jdbc-Treibers, dass es herausfindet, in welcher Zeitzone sich die JVM befindet und sie beim Speichern verwendet.

+0

Sie definieren also Ihre Spalten in der Zeitzone "UTC" und verwenden dann nur LocalDateTime oder ZoneDateTime in den Entitäten und der Geschäftslogik? Und wenn Sie Ihre Daten zurückgeben, konvertieren Sie dann von dieser UTC in die gewünschte TimeZone? – sonoerin

+0

Etwas, ich definiere meine Spalten als Typ Zeitstempel mit Zeitzone, dann, wenn ich meine Zeiten behalte, anstatt nur eine Spalte zu machen =?, Würde ich etwas wie meineSpalte tun =? In der Zeitzone "UTC" werden die Dinge ein bisschen schwierig, da es einfach ist, den Zeitunterschied doppelt zu berücksichtigen. Eine andere Alternative, wenn Sie nach einer guten Lösung auf der ganzen Linie suchen, ist dies als jdbc-Ebene zu setzen. Die Verwendung eines jvm-Parameters wie -Duser.timezone = UTC sollte dies für Sie auf der ganzen Linie tun, und es ist einfacher, ich bin nur unsicher, ob alle Ihre Tabellen UTC oder nur diese benötigen. –

+0

Nach einigen Recherchen sieht es so aus, dass die Werte als MST statt als UTC gespeichert werden, entweder wegen meiner OS/JVM-Umgebungsvariablen. Dies überschreibt meinen Ansatz der Konvertierung nach/aus. Da ich Spring-Data-JPA mit Hibernate und nicht PreparedStatements verwende, muss ich es auf dieser Ebene erzwingen oder sollte ich es beim Starten meiner SpringBoot-App verwenden? – sonoerin

Verwandte Themen