Warum ist der Date-Konstruktor veraltet und was verwende ich stattdessen?

Lesezeit: 6 Minuten

Benutzeravatar von Svish
Schiss

Ich komme aus der C#-Welt, bin also noch nicht allzu erfahren mit Java. Das wurde mir gerade von Eclipse mitgeteilt Date wurde verworfen:

Person p = new Person();
p.setDateOfBirth(new Date(1985, 1, 1));

Warum? Und was (insbesondere in Fällen wie oben) sollte stattdessen verwendet werden?

  • Ich erlebe eine ähnliche Lernkurve und gehe auch von C# zu Java. Die andere Sache, die mich gestört hat, ist, dass der Monat des Jahres ein 0-basiertes System ist (0 bis 11, wobei Jan. = 0 und Dez. = 11), aber die Tage des Monats sind 1-basiert (1 bis 31). Kopf hoch!

    – Paul Sasik

    15. April 2011 um 13:36 Uhr


  • @Paul Sasik, ja, aber es gibt zum Beispiel eine Calendar.JANUARY-Konstante und eine für jeden Monat

    – Diago

    15. April 2011 um 14:07 Uhr

  • @PaulSasik lol. Ja, dummes Java. Musste von C # zu Java wechseln und OMG die Schmerzen und das Elend.

    – cbmeeks

    22. März 2013 um 13:56 Uhr

  • mögliches Duplikat von Warum wurden die meisten java.util.Date-Methoden als veraltet markiert?

    – Thomas

    26. November 2013 um 8:00 Uhr

  • Die bissigen “lol”-Bemerkungen über Java von C#-Leuten Mich lachen, weil .Net seine anständige Datums-Zeit-Bibliothek hat (Noda-Zeit) aus einer Portierung der exzellenten Java-Bibliothek Joda-Zeit.

    – Basilikum Bourque

    6. Februar 2014 um 8:48 Uhr


Benutzeravatar von BuffaloBuffalo
BüffelBüffel

Der java.util.Date class ist nicht wirklich veraltet, nur dieser Konstruktor ist zusammen mit einigen anderen Konstruktoren/Methoden veraltet. Es wurde verworfen, weil diese Art der Verwendung nicht gut mit der Internationalisierung funktioniert. Der Calendar Klasse sollte stattdessen verwendet werden:

Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, 1988);
cal.set(Calendar.MONTH, Calendar.JANUARY);
cal.set(Calendar.DAY_OF_MONTH, 1);
Date dateRepresentation = cal.getTime();

Schauen Sie sich das Datum Javadoc an:

http://download.oracle.com/javase/6/docs/api/java/util/Date.html

  • Dies sollte die beste Antwort sein. Danke.

    – jordaniac89

    28. Mai 2015 um 2:02 Uhr

  • Wenn Sie sagen “funktioniert nicht gut mit Internationalisierung”, meinen Sie, dass Sie für Datum keine Zeitzone zuweisen können? Danke

    – Eintauchen in

    1. Dezember 2015 um 5:55 Uhr


  • Was Date hat einen String geparst, also müssen wir jetzt stattdessen einen String substringen, der das Jahr, den Monat und den Tag enthält? Scheint eine Menge zusätzlicher Aufwand für etwas zu sein, das in den meisten Fällen keine so komplexe Logik und Methoden benötigt, die hinzugefügt werden müssen.

    – G_V

    6. März 2017 um 8:39 Uhr

  • Nur um hinzuzufügen, wird die Standardzeitzone berücksichtigt. Wenn wir eine andere Zeitzone angeben möchten, können wir verwenden Calendar cal = Calendar.getInstance(TimeZone.getTimeZone(<timezone id>));

    – Vikas Prasad

    17. März 2017 um 16:45 Uhr


  • “Stattdessen sollte die Calendar-Klasse verwendet werden” – Für Java 8 und höher ist die java.time.* Klassen sind die bessere Option … wenn Sie Ihren Code ändern.

    – Stefan C

    30. Mai 2018 um 6:15 Uhr


Benutzeravatar von Basil Bourque
Basil Bourque

tl;dr

LocalDate.of( 1985 , 1 , 1 )

…oder…

LocalDate.of( 1985 , Month.JANUARY , 1 )

Einzelheiten

Der java.util.Date, java.util.CalendarUnd java.text.SimpleDateFormat Klassen wurden zu schnell überstürzt, als Java zum ersten Mal gestartet und weiterentwickelt wurde. Die Klassen waren nicht gut konzipiert oder implementiert. Es wurden Verbesserungen versucht, daher die Verwerfungen, die Sie gefunden haben. Leider sind die Verbesserungsversuche weitgehend gescheitert. Du solltest Vermeiden Sie diese Klassen insgesamt. Sie werden in Java 8 durch neue Klassen ersetzt.

Probleme in Ihrem Code

Ein java.util.Date hat sowohl einen Datums- als auch einen Zeitteil. Sie haben den Zeitabschnitt in Ihrem Code ignoriert. Die Date-Klasse nimmt also den Anfang des Tages, wie er durch die Standardzeitzone Ihrer JVM definiert ist, und wendet diese Zeit auf das Date-Objekt an. Die Ergebnisse Ihres Codes variieren also je nachdem, auf welchem ​​​​Computer er ausgeführt wird oder welche Zeitzone eingestellt ist. Wahrscheinlich nicht das, was Sie wollen.

Wenn Sie nur das Datum ohne den Zeitteil möchten, wie z. B. für ein Geburtsdatum, möchten Sie möglicherweise kein a verwenden Date Objekt. Möglicherweise möchten Sie nur eine Zeichenfolge des Datums in speichern ISO 8601 Format von YYYY-MM-DD. Oder verwenden Sie eine LocalDate Objekt von Joda-Time (siehe unten).

Joda-Zeit

Das erste, was Sie in Java lernen sollten: Vermeiden Sie die notorisch problematischen java.util.Date- und java.util.Calendar-Klassen gebündelt mit Java.

Wie in der Antwort von user3277382 richtig angegeben, verwenden Sie entweder Joda-Zeit oder das neue java.time.*-Paket bei Java8.

Beispielcode in Joda-Time 2.3

DateTimeZone timeZoneNorway = DateTimeZone.forID( "Europe/Oslo" );
DateTime birthDateTime_InNorway = new DateTime( 1985, 1, 1, 3, 2, 1, timeZoneNorway );

DateTimeZone timeZoneNewYork = DateTimeZone.forID( "America/New_York" );
DateTime birthDateTime_InNewYork = birthDateTime_InNorway.toDateTime( timeZoneNewYork ); 

DateTime birthDateTime_UtcGmt = birthDateTime_InNorway.toDateTime( DateTimeZone.UTC );

LocalDate birthDate = new LocalDate( 1985, 1, 1 );

Auf Konsole ausgeben…

System.out.println( "birthDateTime_InNorway: " + birthDateTime_InNorway );
System.out.println( "birthDateTime_InNewYork: " + birthDateTime_InNewYork );
System.out.println( "birthDateTime_UtcGmt: " + birthDateTime_UtcGmt );
System.out.println( "birthDate: " + birthDate );

Beim Laufen …

birthDateTime_InNorway: 1985-01-01T03:02:01.000+01:00
birthDateTime_InNewYork: 1984-12-31T21:02:01.000-05:00
birthDateTime_UtcGmt: 1985-01-01T02:02:01.000Z
birthDate: 1985-01-01

java.time

In diesem Fall ist der Code für java.time ist nahezu identisch mit der von Joda-Zeit.

Wir bekommen eine Zeitzone (ZoneId) und erstellen Sie ein dieser Zeitzone zugewiesenes Datum-Uhrzeit-Objekt (ZonedDateTime). Dann mit der Unveränderliche Objekte Muster, erstellen wir neue Datums-Zeiten basierend auf demselben Zeitpunkt des alten Objekts (Anzahl der Nanosekunden seitdem Epoche), aber einer anderen Zeitzone zugewiesen. Zuletzt bekommen wir a LocalDate die keine Tageszeit oder Zeitzone hat, beachten Sie jedoch, dass die Zeitzone bei der Bestimmung dieses Datums gilt (ein neuer Tag dämmert früher in Oslo als in New York Zum Beispiel).

ZoneId zoneId_Norway = ZoneId.of( "Europe/Oslo" );
ZonedDateTime zdt_Norway = ZonedDateTime.of( 1985 , 1 , 1 , 3 , 2 , 1 , 0 , zoneId_Norway );

ZoneId zoneId_NewYork = ZonedId.of( "America/New_York" );
ZonedDateTime zdt_NewYork = zdt_Norway.withZoneSameInstant( zoneId_NewYork );

ZonedDateTime zdt_Utc = zdt_Norway.withZoneSameInstant( ZoneOffset.UTC );  // Or, next line is similar.
Instant instant = zdt_Norway.toInstant();  // Instant is always in UTC.

LocalDate localDate_Norway = zdt_Norway.toLocalDate();

Um java.time

Der java.time Framework ist in Java 8 und höher integriert. Diese Klassen ersetzen die lästigen alten Vermächtnis Datum-Zeit-Klassen wie z java.util.Date, Calendar& SimpleDateFormat.

Weitere Informationen finden Sie unter Oracle-Tutorial. Und durchsuchen Sie Stack Overflow nach vielen Beispielen und Erklärungen. Spezifikation ist JSR310.

Der Joda-Zeit Projekt, jetzt in Wartungsmodusrät zur Migration in die java.time Klassen.

Sie dürfen umtauschen java.time Objekte direkt mit Ihrer Datenbank. Benutze einen JDBC-Treiber gemäß JDBC 4.2 oder später. Keine Notwendigkeit für Saiten, keine Notwendigkeit für java.sql.* Klassen. Unterstützung für Hibernate 5 und JPA 2.2 java.time.

Wo erhalte ich die java.time-Klassen?

  • Java SE 8, Java SE 9, JavaSE 10, Java SE 11und höher – Teil der Standard-Java-API mit einer gebündelten Implementierung.
    • Java 9 brachte einige kleinere Funktionen und Korrekturen.
  • Java SE 6 Und Java SE 7
    • Die meisten von den java.time Funktionalität ist zurückportiert auf Java 6 & 7 in ThreeTen-Backport.
  • Android
    • Spätere Versionen von Android (26+) bündeln Implementierungen der java.time Klassen.
    • Für frühere Android-Versionen (<26) ermöglichen die neuesten Android-Tools einen Prozess namens API-Entzuckerung bieten ein Teilmenge der java.time Funktionen, die ursprünglich nicht in Android integriert waren.
      • Wenn die Entzuckerung nicht das bietet, was Sie brauchen, die ThreeTenABP Projekt passt ThreeTen-Backport (oben erwähnt) auf Android. Sehen Wie benutzt man ThreeTenABP….

Tabelle, welche java.time-Bibliothek mit welcher Java- oder Android-Version verwendet werden soll

  • Requisiten, um die eigentliche Ursache zu erwähnen und alle verfügbaren Alternativen abzudecken.

    – mabi

    11. April 2016 um 13:52 Uhr

  • Dies ist die richtige Antwort und die Kalenderklasse sollte vermieden werden. ThreeTen ist die beste Option

    – Ameise2009

    16. November 2019 um 14:21 Uhr


  • @Basil Bourque Sie erwähnen spätere Versionen von Android-Bundle-Implementierungen von java.time-Klassen. Kannst du genauer sagen welche Versionen? Ich versuche, alten Datums- und Kalendercode für eine Android-App zu ersetzen, bin mir aber nicht sicher, wo ich anfangen soll.

    – AJW

    22. November 2021 um 3:37 Uhr


  • @AJW Diese Informationen sind bereits im letzten Abschnitt der Antwort “Über java.time” enthalten, die ich gerade aktualisiert habe.

    – Basilikum Bourque

    22. November 2021 um 6:10 Uhr


  • Sehr gut, danke für das Update.

    – AJW

    22. November 2021 um 15:17 Uhr

Rubens Benutzeravatar
Ruben

Das spezifische Date Konstruktor ist veraltet, und Calendar sollte stattdessen verwendet werden. Der JavaDoc für Datum beschreibt, welche Konstruktoren veraltet sind und wie sie mit a ersetzt werden Calendar.

  • Der Kalender erfordert ein zusätzliches Objekt und etwa 8 Zeilen mehr Code, um dasselbe zu tun, nämlich ein Date-Objekt zu erstellen, von dem, was ich sagen kann. Es ist verwirrend und erscheint unnötig, wenn Sie nur ein Datum und keine zeitzonenangepasste Variable benötigen.

    – G_V

    6. März 2017 um 8:37 Uhr

  • FYI, die furchtbar lästigen alten Datums-Zeit-Klassen wie java.util.Date, java.util.CalendarUnd java.text.SimpleDateFormat sind jetzt Vermächtnisersetzt durch die java.time Klassen, die in Java 8 und höher integriert sind. Sehen Lernprogramm von Oracle.

    – Basilikum Bourque

    28. November 2018 um 19:18 Uhr

Benutzeravatar von Kevin Workman
Kevin Workman

Ich bin auf diese Frage als Duplikat einer neueren Frage gestoßen, in der gefragt wurde, wie man a erhält Date in einem bestimmten Jahr, Monat und Tag war.

Die Antworten hier bisher sagen, um die zu verwenden Calendar Klasse, und das galt, bis Java 8 herauskam. Aber ab Java 8 ist dies standardmäßig so:

LocalDate localDate = LocalDate.of(1985, 1, 1);

Und dann, wenn Sie wirklich wirklich brauchen java.util.Datekönnen Sie die Vorschläge in dieser Frage verwenden.

Weitere Informationen finden Sie unter die API oder die Tutorien für Java8.

Benutzeravatar von Stephen C
Stefan C

Ein Grund dafür, dass der Konstruktor veraltet ist, ist, dass die Bedeutung des year-Parameters nicht Ihren Erwartungen entspricht. Der Javadoc sagt:

Ab JDK-Version 1.1 ersetzt durch Calendar.set(year + 1900, month, date).

Beachten Sie, dass das Feld year die Anzahl der Jahre seither ist 1900, sodass Ihr Beispielcode höchstwahrscheinlich nicht das tut, was Sie erwarten. Und das ist der Punkt.

Im Allgemeinen ist die Date Die API unterstützt nur den modernen westlichen Kalender, hat eigenwillig spezifizierte Komponenten und verhält sich inkonsistent, wenn Sie Felder festlegen.

Der Calendar Und GregorianCalendar APIs sind besser als Date, und die Joda-Time-APIs von Drittanbietern wurden allgemein als die besten angesehen. In Java 8 führten sie die java.time Pakete, und diese sind jetzt die empfohlene Alternative.

  • Diese Lösung funktioniert hervorragend, außer dass sie keine Nullzeit für Stunden-Minuten-Sekunden-Millisekunden verwendet, wie es bei new Date(year, month, day) der Fall war. Wir brauchen also so etwas wie: Calendar cal = Calendar.getInstance(); cal.clear(); cal.set(Jahr + 1900, Monat, Datum); Datum dateRepresentation = cal.getTime();

    – Joel Richard Koett

    3. Mai 2019 um 23:02 Uhr


Benutzeravatar von nbrooks
nbäche

Bitte beachte, dass Calendar.getTime() ist nicht deterministisch in dem Sinne, dass die Tageszeit Teil ist standardmäßig auf die aktuelle Zeit eingestellt.

Versuchen Sie zur Reproduktion, den folgenden Code ein paar Mal auszuführen:

Calendar c = Calendar.getInstance();
c.set(2010, 2, 7); // NB: 2 means March, not February!
System.err.println(c.getTime());

Ausgabe zB:

Sun Mar 07 10:46:21 CET 2010

Das Ausführen des exakt gleichen Codes ein paar Minuten später ergibt:

Sun Mar 07 10:57:51 CET 2010

Also, während set() zwingt entsprechende Felder zu korrekten Werten, es verliert Systemzeit für die anderen Felder. (Oben getestet mit Sun jdk6 & jdk7)

  • Diese Lösung funktioniert hervorragend, außer dass sie keine Nullzeit für Stunden-Minuten-Sekunden-Millisekunden verwendet, wie es bei new Date(year, month, day) der Fall war. Wir brauchen also so etwas wie: Calendar cal = Calendar.getInstance(); cal.clear(); cal.set(Jahr + 1900, Monat, Datum); Datum dateRepresentation = cal.getTime();

    – Joel Richard Koett

    3. Mai 2019 um 23:02 Uhr


Benutzeravatar von Rob W
Rob W

Date selbst ist nicht veraltet. Es ist nur eine Menge seiner Methoden. Siehe hier für Details.

Verwenden java.util.Calendar stattdessen.

1445080cookie-checkWarum ist der Date-Konstruktor veraltet und was verwende ich stattdessen?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy