Ich spiele gerade mit dem neuen Paket java.time in Java 8. Ich habe eine ältere Datenbank, die mir java.util.Date
gibt, die ich in Instant
umwandle.Java 8 java.time: Hinzufügen von TemporalUnit in Instant vs LocalDateTime
Was ich versuche, ist ein Zeitraum hinzuzufügen, der auf einem anderen Datenbankflag basiert. Ich könnte Tage, Wochen, Monate oder Jahre hinzufügen. Ich möchte mich nicht darum kümmern müssen, was ich hinzufügen möchte, und ich würde gerne in der Zukunft weitere Optionen hinzufügen können.
Mein erster Gedanke war Instant.plus()
, aber das gibt mir eine UnsupportedTemporalTypeException
für Werte größer als einen Tag. Instant unterstützt anscheinend keine Operationen in großen Zeiteinheiten. Gut, was auch immer, LocalDateTime
tut.
So gibt, dass mir diesen Code:
private Date adjustDate(Date myDate, TemporalUnit unit){
Instant instant = myDate.toInstant();
LocalDateTime dateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
dateTime = dateTime.plus(1, unit);
Instant updatedInstant = dateTime.atZone(ZoneId.systemDefault()).toInstant();
return new Date(dueInstant.toEpochMilli());
}
Nun, dies ist mein erstes Mal die neue Zeit-API, so dass ich kann hier etwas übersehen haben. Aber es scheint klobig zu mir, dass ich gehen muss:
Date --> Instant --> LocalDateTime --> do stuff--> Instant --> Date.
Auch wenn ich nicht das Datum Teil verwenden hatte, würde ich immer noch denke, es ist ein wenig umständlich war. Meine Frage ist also, mache ich das völlig falsch und was ist der beste Weg dies zu tun?
bearbeiten: in den Kommentaren über die Diskussion zu erweitern.
Ich denke, ich habe jetzt eine bessere Idee darüber, wie LocalDateTime und Instant mit java.util.Date und java.sql.Timestamp spielen. Danke an alle.
Nun, eine praktische Überlegung. Nehmen wir an, ein Benutzer sendet mir ein Datum von einer beliebigen Zeitzone in der Welt. Sie senden mir 2014-04-16T13:00:00
, die ich in eine LocalDateTime analysieren kann. Ich konvertiere das dann direkt in einen java.sql.Timestamp und behalte es in meiner Datenbank bei.
Nun, ohne etwas anderes zu tun, ziehe ich meine java.sql.timestamp aus meiner Datenbank, umwandeln zu LocalDateTime
mit timestamp.toLocalDateTime()
. Alles gut. Dann gebe ich diesen Wert mithilfe der ISO_DATE_TIME-Formatierung an meinen Benutzer zurück. Das Ergebnis ist 2014-04-16T09:00:00
.
Ich nehme an, dass dieser Unterschied wegen einer Art von impliziter Konvertierung zu/von UTC ist. Ich denke, dass meine Standardzeitzone auf den Wert (EDT, UTC-4) angewendet wird, der erklären würde, warum die Zahl um 4 Stunden aus ist.
Neue Frage (n). Wo passiert hier die implizite Konvertierung von Ortszeit in UTC? Was ist der bessere Weg Zeitzonen zu erhalten? Sollte ich nicht direkt von Ortszeit als String (2014-04-16T13: 00: 00) zu LocalDateTime
gehen? Sollte ich von den Benutzereingaben eine Zeitzone erwarten?
Welchen Wert sollen Sie hier darstellen? Ein 'Instant' kennt * logischerweise * nichts über ein Kalendersystem - es ist nur ein Zeitpunkt -, daher ist es nicht sinnvoll, einen Monat hinzuzufügen. Sie sollten auch sorgfältig abwägen, ob Sie * wirklich * die Systemzeitzone verwenden möchten - möchten Sie je nach Einsatzort unterschiedliche Ergebnisse für die gleichen Werte erhalten? –
@JonSkeet Wäre es angemessener, eine ZoneId dann willkürlich auszuwählen? Immer GMT oder so? Es scheint, als könnte das mit einer eigenen Reihe von Problemen kommen. Vielleicht ist das Problem, dass ich nicht weiß, wie ich meine java.util.date darstellen soll. Ich habe einen Zeitpunkt. Wenn bestimmte Bedingungen erfüllt sind, möchte ich diesen Punkt in Zukunft auf einen Monat (oder Tag, Jahr, was auch immer) ändern. – jacobhyphenated
Die Verwendung von UTC kann die beste Option sein, aber Sie müssen wirklich darüber nachdenken, was Ihre Anforderungen sind. Was bedeutet es sogar, einen Zeitpunkt (ohne Zeitzone oder Kalender) um einen Monat zu ändern? –