Ich erhalte die folgende Ausnahme bei dem Versuch , konvertieren java.util.Date
zu java.time.LocalDate
.
java.time.DateTimeException: Unable to obtain ZonedDateTime from TemporalAccessor: 2014-08-19T05:28:16.768Z of type java.time.Instant
Der Code lautet wie folgt:
public static Date getNearestQuarterStartDate(Date calculateFromDate){
int[] quaterStartMonths={1,4,7,10};
Date startDate=null;
ZonedDateTime d=ZonedDateTime.from(calculateFromDate.toInstant());
int frmDateMonth=d.getMonth().getValue();
Stimmt etwas nicht mit der Art und Weise, wie ich die ZonedDateTime
Klasse benutze ?
Gemäß Dokumentation sollte dies ein java.util.Date
Objekt in konvertieren ZonedDateTime
. Das obige Datumsformat ist Standarddatum?
Muss ich auf Joda zurückgreifen?
Wenn jemand einen Vorschlag machen könnte, wäre es großartig.
Date
ähnelt aInstant
, die beide UNIX-Zeitstempel sind. Es ist auch üblich zu sagen, dass UNIX-Zeitstempel UTC-Zeitzonen sind.Um eine ZonedDateTime von einem Datum zu erhalten, können Sie Folgendes verwenden:
Sie können die
toLocalDate
Methode dann aufrufen , wenn Sie ein LocalDate benötigen. Siehe auch: Konvertieren Sie java.util.Date in java.time.LocalDatequelle
Die Antwort von Assylias und die Antwort von JB Nizet sind beide richtig:
java.util.Date::toInstant
.Instant::atZone
und übergeben Sie aZoneId
, was zu a führtZonedDateTime
.Ihr Codebeispiel richtet sich jedoch an Quartale. Lesen Sie dazu weiter.
Viertel
Sie müssen Ihre Quartiere nicht selbst verwalten. Verwenden Sie eine bereits geschriebene und getestete Klasse.
org.threeten.extra.YearQuarter
Die java.time- Klassen werden durch das ThreeTen-Extra- Projekt erweitert. Unter den vielen praktischen Klassen, die in dieser Bibliothek angeboten werden, finden Sie
Quarter
undYearQuarter
.Holen Sie sich zuerst Ihre
ZonedDateTime
.ZonedId z = ZoneID.of( "Africa/Tunis" ) ; ZonedDateTime zdt = myJavaUtilDate.toInstant().atZone( z ) ;
Bestimmen Sie das Jahresquartal für dieses bestimmte Datum.
Als nächstes brauchen wir das Startdatum dieses Quartals.
LocalDate quarterStart = yq.atDay( 1 ) ;
Obwohl ich dies nicht unbedingt empfehle, können Sie eine einzelne Codezeile verwenden, anstatt eine Methode zu implementieren.
LocalDate quarterStart = // Represent a date-only, without time-of-day and without time zone. YearQuarter // Represent a specific quarter using the ThreeTen-Extra class `org.threeten.extra.YearQuarter`. .from( // Given a moment, determine its year-quarter. myJavaUtilDate // Terrible legacy class `java.util.Date` represents a moment in UTC as a count of milliseconds since the epoch of 1970-01-01T00:00:00Z. Avoid using this class if at all possible. .toInstant() // New method on old class to convert from legacy to modern. `Instant` represents a moment in UTC as a count of nanoseconds since the epoch of 1970-01-01T00:00:00Z. .atZone( // Adjust from UTC to the wall-clock time used by the people of a particular region (a time zone). Same moment, same point on the timeline, different wall-clock time. ZoneID.of( "Africa/Tunis" ) // Specify a time zone using proper `Continent/Region` format. Never use 2-4 letter pseudo-zone such as `PST` or `EST` or `IST`. ) // Returns a `ZonedDateTime` object. ) // Returns a `YearQuarter` object. .atDay( 1 ) // Returns a `LocalDate` object, the first day of the quarter. ;
Übrigens, wenn Sie Ihre Nutzung
java.util.Date
insgesamt auslaufen lassen können , tun Sie dies. Es ist eine schreckliche Klasse, zusammen mit seinen Geschwistern wieCalendar
. Verwenden SieDate
nur dort, wo Sie müssen, wenn Sie mit altem Code arbeiten, der noch nicht auf java.time aktualisiert wurde .Über java.time
Das java.time- Framework ist in Java 8 und höher integriert. Diese Klassen verdrängen die lästigen alten Legacy - Datum-Zeit - Klassen wie
java.util.Date
,Calendar
, &SimpleDateFormat
.Weitere Informationen finden Sie im Oracle-Lernprogramm . Suchen Sie im Stapelüberlauf nach vielen Beispielen und Erklärungen. Die Spezifikation ist JSR 310 .
Das Joda-Time- Projekt, das sich jetzt im Wartungsmodus befindet , empfiehlt die Migration zu den Klassen java.time .
Sie können java.time- Objekte direkt mit Ihrer Datenbank austauschen . Verwenden Sie einen JDBC-Treiber, der mit JDBC 4.2 oder höher kompatibel ist . Keine Notwendigkeit für Zeichenfolgen, keine Notwendigkeit für
java.sql.*
Klassen.Woher bekomme ich die java.time-Klassen?
Das ThreeTen-Extra- Projekt erweitert java.time um zusätzliche Klassen. Dieses Projekt ist ein Testfeld für mögliche zukünftige Ergänzungen von java.time. Sie können einige nützliche Klassen hier wie finden
Interval
,YearWeek
,YearQuarter
, und mehr .quelle
Die Antwort hat bei Java 10, bei dem util.Date in UTC gespeichert wurde, nicht funktioniert.
Date.toInstant () scheint das EpochMillis in die lokale Zeitzone des Servers zu konvertieren.
ZDT.ofInstant (Instant, ZoneId) und Instant.atZone (ZoneId) scheinen im Moment nur eine TZ zu markieren, aber es ist bereits durcheinander.
Ich konnte keinen Weg finden, um zu verhindern, dass Date.toInstant () mit der UTC-Zeit und der Systemzeitzone in Konflikt gerät.
Die einzige Möglichkeit, dies zu umgehen, bestand darin, die sql.Timestamp-Klasse durchzugehen:
new java.sql.Timestamp(date.getTime()).toLocalDateTime() .atZone(ZoneId.of("UTC")) .withZoneSameInstant(desiredTZ)
quelle
Date::toInstant
. Sowohl ajava.util.Date
als auch ajava.time.Instant
sind per Definition in UTC, immer in UTC.Date
stellt eine Anzahl von Millisekunden seit der Epoche von 1970-01-01T00: 00: 00Z dar, währendInstant
es sich auch um eine Zählung seit derselben Epoche handelt, jedoch mit einer feineren Auflösung von Nanosekunden.LocalDateTime
ist genau die falsche Klasse, die hier verwendet wird. Dieser Klasse fehlt absichtlich jedes Konzept der Zeitzone oder des Versatzes von UTC. Als solches ist es nicht in der Lage, einen Moment darzustellen, wie in seiner Klasse JavaDoc angegeben. Beim Konvertieren in a werdenLocalDateTime
wertvolle Informationen verworfen, ohne dass etwas gewonnen wird. Diese Antwort ist irreführend und falsch. Siehe die richtige Antwort von Assylias. Alles was Sie brauchen, um einZonedDateTime
von einem zu bekommen,Date
ist :myJavaUtilDate.toInstant().atZone( desiredZoneIdGoesHere )
.java.sql.Timestamp
wieder zu verwenden, jetzt ersetzt durchjava.sql.OffsetDateTime
- ab JDBC 4.2 können wir einige java.time- Typen direkt mit der Datenbank austauschen .