2017-10-18 3 views
0

Ich arbeite mit Clock In/Out-Funktionalität von einem Web-Portal, auf das von Terminals in verschiedenen Zeitzonen zugegriffen werden kann.Spring JDBC Persist ZonedDateTime

Ich benutze ZonedDateTime um zu berechnen, wie die Datetime für einen bestimmten Punch-In/Out-Datensatz sein sollte.

// Get store timezone 
ZoneId storeTimeZone = this.storeService.getStoreZoneId(storeNum); 

// Get current store time to use for punch in/out timestamp 
ZonedDateTime currentStoreTime = ZonedDateTime.ofInstant(Instant.now(), storeTimeZone); 

Wenn ich die Daten in Oracle 11g bestehen bleiben kann ich nicht ZonedDateTime Objekt bestehen. Wird wahrscheinlich nicht vom JDBC-Treiber unterstützt. Es ist eine Unternehmensumgebung, so dass Datenbank und Treiber sich nicht ändern werden.

Wenn ich die MapSqlParamSource erstellen, um in NamedParameterJdbcTemplate zu übergeben, muss ich es in eine java.sql.Timestamp konvertieren, aber dann verliere ich die Zonendaten und den Zeitstempel für die Zeitzone, in der sich der Server befindet, Anforderungen diktieren Es muss in der Speicherzeit in der Datenbank gespeichert werden, die nur eine Oracle TIMESTAMP-Spalte ist.

params.addValue("clockInTimestamp", Timestamp.from(prevRecord.getTimeEntryTimestamp().toInstant()), Types.TIMESTAMP); 

Gibt es eine Möglichkeit, diese persistente ZoneDateTime zu erreichen?

+0

Vergessen Sie die Details von Spring, JDBC etc - es klingt wie Sie versuchen, "Instant + Zeitzone" in einem Feld zu speichern, die nur einen Augenblick speichern kann ... so dass es nicht mehr als "I möchte 32 Bytes Daten in einem 4-Byte-Feld speichern "würde. Ich schlage vor, dass Sie herausfinden, welche Informationen Sie speichern möchten und auf welche Weise * dann * herausfinden, wie Sie es erreichen können. –

Antwort

1

Sprint Boot-Projekte werden automatisch geladen jsr310jpaconverters, aber dies wird nur Konvertierung von LocalDateTime Typ, nicht ZonedDateTime. Wenn Sie Spring Boot nicht verwenden, können Sie diese zusätzlichen Konverter selbst laden.

Vielleicht mögen Sie Ihre Anwendung anzupassen Verwendung die in der Datenbank Interaktionsebene zu machen und einfach alles, was Sie in einer Standard-Zeitzone zu speichern zwingen, so dass Sie leicht zu ZonedDateTime umwandeln können, wenn für den Benutzer zu Anzeigezwecken erforderlich.

0

Ich konnte dieses Problem lösen, indem ich von "ZonedDateTime" in "Instant" umwandelte und dann manuell den Zeitstempel mit den Offsets der Zeitzone berechnete.

Beispiel-Code unten:

ZonedDateTime timeEntry = ZonedDateTime.now(); 

ZoneOffset storeOffset = timeEntry.getOffset(); 
ZoneOffset serverOffset = ZonedDateTime.now().getOffset(); 

int secondsOffset = storeOffset.getTotalSeconds() - serverOffset.getTotalSeconds(); 

Instant entryTimestamp = timeEntry.toInstant().plusSeconds(secondsOffset); 

Timestamp ts = Timestamp.from(entryTimestamp); 

Und dann beharren ich die java.sql.Timestamp in die Datenbank.

Nicht die sauberste oder beste Lösung, die ich sicher bin, aber mit den Einschränkungen, Datenbank, Treiber oder andere Dinge nicht ändern zu können, scheint es gut zu sein.

Verwandte Themen