Frage

Könnte jemand bitte den aktuellen "best practice" um Date und Calendar Typen beraten.

Wenn neuen Code zu schreiben, ist es am besten, immer bevorzugt Calendar über Date, oder gibt es Umstände, unter denen Date ist der geeignetere Datentyp?

War es hilfreich?

Lösung

Datum ist eine einfachere Klasse und ist in erster Linie dort aus Gründen der Abwärtskompatibilitätsgründen. Wenn Sie bestimmte Termine festlegen müssen oder Datumsberechnungen zu tun, verwenden Sie einen Kalender. Kalender behandelt auch die Lokalisierung. Die bisherigen Datum Manipulation Funktionen Datum seit veraltet.

Persönlich neige ich dazu, entweder Zeit in Millisekunden als lange (oder lang, je nach Bedarf) oder Kalender zu verwenden, wenn es eine Wahl ist.

Sowohl Datum und Kalender sind wandelbar, die Dinge darzustellen neigt, wenn sie in einer API entweder mit.

Andere Tipps

Der beste Weg für neuen Code (wenn Ihre Politik Code von Drittanbietern ermöglicht) ist die Joda Zeit-Bibliothek zu verwenden .

Sowohl Datum und Kalender , haben so viele Design-Probleme weder, dass es gute Lösungen für neuen Code.

  • Date und Calendar ist wirklich das gleiche Grundkonzept (beide für einen Zeitpunkt und sind Wrapper um einen darunter liegenden long Wert).

  • Man könnte argumentieren, dass Calendar als tatsächlich noch mehr kaputt ist Date , da es konkrete Fakten über Dinge wie Wochentag und Tageszeit zu bieten scheint, während, wenn Sie ändern seine timeZone Eigenschaft, wird der Beton in blancmange! Weder Objekte sind wirklich nützlich als Speicher von Jahr-Monat-Tag oder time-of-Tag aus diesem Grund.

  • Verwenden Sie Calendar nur als Taschenrechner, die bei Date und TimeZone Objekte gegeben, wird für Sie Berechnungen tun. Vermeiden Sie die Verwendung für Eigenschaft der Eingabe in einer Anwendung.

  • Mit SimpleDateFormat zusammen mit TimeZone und Date zu Display Strings erzeugen.

  • Wenn Sie abenteuerlich Verwendung Joda-Time Gefühl sind, obwohl es meiner Meinung nach unnötig kompliziert ist und bald von der JSR-310 Datum API auf jeden Fall superceded werden.

  • Ich habe vor geantwortet, dass es nicht schwierig ist, Ihre eigene YearMonthDay Klasse zu rollen, die für die Datumsberechnungen Calendar unter der Haube verwendet. Ich war für den Vorschlag Downvoted aber ich glaube, es ist immer noch ein gültiger weil Joda-Time ( und JSR-310 ) sind wirklich so zu kompliziert für die meisten anwendungs~~POS=TRUNC.

Datum ist am besten für ein Date-Objekt zu speichern. Es ist die persistente ein, die serialisierten ein ...

Kalender ist am besten für die Manipulation von Daten.

  

Hinweis: wir manchmal auch java.lang.Long über Datum bevorzugen, weil Datum wandelbar ist und deshalb nicht Thread-sicher. Auf einem Date-Objekt verwenden setTime () und getTime () zwischen den beiden zu wechseln. Zum Beispiel kann ein Konstante Datum in der Anwendung (Beispiele: die Null 1970.01.01 oder einen applicative END_OF_TIME, die Sie 2099.12.31 gesetzt, das ist sehr nützlich Nullwerte als Startzeit und die Endzeit zu ersetzen, vor allem wenn Sie beharren sie in der Datenbank, wie SQL mit Nullen so eigentümlich ist).

Ich benutze Datum im Allgemeinen, wenn möglich. Obwohl es wandelbar ist, werden die Mutatoren eigentlich veraltet. Am Ende wickelt es im Grunde eine lange, die das Datum / Zeit darstellen würde. Im Gegensatz dazu würde ich Kalender verwenden, wenn ich die Werte manipulieren.

Sie können es auf diese Art und Weise denken: Sie nur verwenden, wenn Sie Strings String haben müssen, die Sie leicht manipulieren und sie dann in Strings konvertieren Methode toString (). In der gleichen Art und Weise, ich benutze Kalender nur, wenn ich temporale Daten manipulieren muß.

Für Best Practice, neige ich dazu, so viel wie möglich unveränderliche Objekte zu verwenden, außerhalb des Domänenmodell . Es reduziert deutlich die Chancen von Nebenwirkungen, und es wird für Dich durch den Compiler, sondern als ein JUnit-Test durchgeführt. Sie verwenden diese Technik durch die Schaffung von Private final Felder in Ihrer Klasse.

Und kommt zurück auf die String Analogie. Hier ist ein Code, der zeigt, wie zwischen Kalender und Datum konvertieren

String s = "someString"; // immutable string
StringBuffer buf = new StringBuffer(s); // mutable "string" via StringBuffer
buf.append("x");
assertEquals("someStringx", buf.toString()); // convert to immutable String

// immutable date with hard coded format.  If you are hard
// coding the format, best practice is to hard code the locale
// of the format string, otherwise people in some parts of Europe
// are going to be mad at you.
Date date =     new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH).parse("2001-01-02");

// Convert Date to a Calendar
Calendar cal = Calendar.getInstance();
cal.setTime(date);

// mutate the value
cal.add(Calendar.YEAR, 1);

// convert back to Date
Date newDate = cal.getTime();

// 
assertEquals(new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH).parse("2002-01-02"), newDate);

Dates sollte als unveränderliche Zeitpunkt verwendet werden; Calendars sind wandelbar und kann sich um und verändert weitergegeben werden, wenn Sie mit anderen Klassen müssen zusammenarbeiten mit einem Endtermin kommen. Betrachten sie analog String und StringBuilder und Sie werden verstehen, wie ich in Betracht ziehen sollten sie verwendet werden.

(Und ja, ich weiß, Datum nicht wirklich technisch unveränderlich ist, aber die Absicht ist, dass es nicht wandelbar sein sollte, und wenn nichts, um die veralteten Methoden aufruft, dann ist es so.)

tl; dr

  

berät die aktuellen "best practice" um Date und Calendar

     

ist es am besten, immer Calendar über Date bevorzugen

Vermeiden Sie diese Legacy-Klassen vollständig. Verwenden Sie java.time Klassen statt .

  • Einen Moment lang in UTC , verwenden Sie Instant
    (das moderne Äquivalent von Date)
  • Einen Moment lang in einem bestimmten Zeitzone ZonedDateTime
    (das moderne Äquivalent von GregorianCalendar)
  • Einen Moment lang in einem bestimmten Offset-from-UTC , verwenden Sie OffsetDateTime
    (kein Äquivalent in Legacy-Klassen)
  • Für eine Datum-Zeit (keinen Moment) mit unbekannter Zeitzone oder versetzt, verwenden Sie LocalDateTime
    (kein Äquivalent in Legacy-Klassen)

Details

Die Antwort von Ortomala Lokni ist Recht vorzuschlagen, um den modernen java.time Klassen statt der lästigen alten Legacy-Datum-Zeit-Klassen (Date, Calendar, etc.). Aber das Antwort schlägt die falsche Klasse als gleichwertig (siehe meinen Kommentar auf dieser Antwort).

Mit java.time

Die java.time Klassen sind eine große Verbesserung gegenüber den Legacy-Datum-Zeit-Klassen, Nacht wie Tag und Differenz. Die alten Klassen sind schlecht gestaltete, verwirrend und lästig. Sie sollen die alten Klassen, wann immer möglich vermeiden. Aber wenn man zum / vom alten / neuen konvertieren müssen, können Sie dies tun, indem Aufruf neue Methoden ergänzen die alt Klassen.

Für viel mehr Informationen über die Konvertierung finden Sie unter meine Antwort und geschicktes Diagramm auf eine andere Frage, Konvertieren java.util.Date zu dem, was ‚java.time‘ Typ

?.

Suchen Stack-Überlauf gibt viele Hunderte von Beispiel Fragen und Antworten auf java.time verwenden. Aber hier ist eine kurze Zusammenfassung.

Instant

den aktuellen Moment mit einem Instant Get. Die Instant Klasse stellt einen Moment auf die Timeline in UTC mit einer Auflösung von ns (bis zu neun (9) Stellen einer Dezimalbruch).

Instant instant = Instant.now();

ZonedDateTime

Um dieses same gleichzeitige Moment zu sehen durch die Linse einiger Wand-Uhr-Zeit , eine Zeitzone ( ZoneId ) eine ZonedDateTime .

Zeitzone

Geben Sie eine rel="nofollow richtige Zeitzone Namen im Format continent/region wie America/Montreal , Africa/Casablanca oder Pacific/Auckland. Verwenden Sie niemals die 3-4 Buchstaben-Abkürzung wie EST oder IST, wie sie sind nicht true Zeitzonen, nicht standardisiert, und nicht einmal eindeutig (!).

ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone();

Offset

Eine Zeitzone ist eine Geschichte der Veränderungen in der Region in seinem Offset-from-UTC . Aber manchmal sind Sie nur eine Offset ohne die volle Zone gegeben. In diesem Fall verwenden Sie die OffsetDateTime Klasse.

ZoneOffset offset = ZoneOffset.parse( "+05:30" );
OffsetDateTime odt = instant.atOffset( offset );

Die Verwendung einer Zeitzone ist bevorzugt gegenüber der Verwendung von nur gegenüber.

LocalDateTime

Die „Local“ in den Local… Klassen Mittel jeder Ort, nicht eine bestimmte Lokalität. So kann der Name sein kontraintuitiv.

LocalDateTime, LocalDate und LocalTime fehlen absichtlich keine Informationen über Offset- oder Zeitzone. Und sie tun nicht tatsächlichen Momente darstellen, sind sie nicht Punkte auf der Timeline. Im Zweifelsfall oder wenn in Verwirrung, verwendet ZonedDateTime statt LocalDateTime. Suchen Stack-Überlauf für viel Diskussion.

Strings

Sie Datum-Zeit-Objekte mit Streichern nicht conflate, die ihren Wert darstellen. Sie können einen String parsen ein Datum-Zeit-Objekt zu erhalten, und Sie können eine Zeichenfolge aus einem Datetime-Objekt erzeugen. Aber die Zeichenfolge nie das Datum-Zeit selbst.

Erfahren Sie mehr über Standard ISO 8601 Formate rel="nofollow, die standardmäßig in den java.time Klassen verwendet.


über java.time

Die java.time Rahmen in Java 8 gebaut und später. Diese Klassen verdrängen die störenden alten Vermächtnis Datum Zeitklassen rel="nofollow wie java.util.Date , Calendar & SimpleDateFormat .

Die Joda-Time Projekt jetzt in < a href = "https://en.wikipedia.org/wiki/Maintenance_mode" rel = "nofollow noreferrer"> Wartungsmodus , rät Migration auf die java.time Klassen.

Um mehr zu erfahren, finden Sie in der Oracle Tutorial . Und Stack-Überlauf suchen viele Beispiele und Erklärungen. Spezifikation JSR 310 .

Mit einem JDBC-Treiber kompatibel mit JDBC 4.2 oder später, können Sie java.time Objekte direkt mit Ihrer Datenbank auszutauschen. Keine Notwendigkeit für Strings noch java.sql. * Klassen.

Wo die java.time Klassen erhalten?

Das ThreeTen-Extra Projekt erstreckt java.time mit zusätzlichen Klassen. Dieses Projekt ist eine Bewährungsprobe für eine mögliche zukünftige Ergänzungen java.time. Sie können einige nützliche Klassen hier wie Interval YearWeek , YearQuarter und mehr .

Mit Java 8, die neuen java .Time Paket verwendet werden soll.

Die Objekte sind unveränderlich, Zeitzonen und Tageslichteinsparung berücksichtigt werden.

Sie können erstellen ZonedDateTime Objekt aus einem alten java.util.Date Objekt wie folgt :

    Date date = new Date();
    ZonedDateTime zonedDateTime = date.toInstant().atZone(ZoneId.systemDefault());

ich immer befürworten Joda Zeit . Hier ist der Grund.

  1. die API ist konsistent und intuitiv. Im Gegensatz zu dem java.util.Date/Calendar APIs
  2. es nicht aus Threadingprobleme nicht leiden, im Gegensatz zu java.text.SimpleDateFormat usw. (ich habe im Zusammenhang zahlreiche Kundenfragen gesehen nicht ahnend, dass die Standard-Datum / Zeit-Formatierung ist nicht Thread-sicher)
  3. es ist die Grundlage des neuen Java-Datum / Zeit-APIs ( JSR310 für Java geplant, 8. So werden Sie mit APIs, die Core Java-APIs werden wird.

EDIT: Die Java-Datum / Zeit-Klassen eingeführt mit Java 8 sind nun die bevorzugte Lösung, wenn Sie Java 8 migrieren können

Ein wenig spät in der Partei, aber Java hat ein neues Datum Zeit API in JDK 8. Sie möchten Ihre JDK-Version und umarmen, den Standard aktualisieren. No more unordentliches Datum / Kalender, nicht mehr 3rd-Party-Gläser.

Datum sollte neu entwickelt werden. Anstatt eine lange interger zu sein, sollte es für Jahr, Monat, Tag, Stunde, Minute, Sekunde, als separate Felder halten. Es könnte sogar gut sein, den Kalender und die Zeitzone zu speichern dieses Datum verknüpft ist.

In unserer natürlichen Gespräch, wenn Setup einen Termin am 1. November 2013 01.00 Uhr New Yorker Zeit, dies ist ein Datetime. Es ist kein Kalender. Also sollten wir auch, wie dies in Java zu unterhalten können.

Wenn Datum als long integer (von mili Sekunden seit dem 1. Januar 1970 oder etwas) gespeichert wird, hängt von dem Kalender des aktuellen Zeitpunkt berechnet wird. Verschiedene Kalender werden verschiedene Daten geben. Dies ist aus dem prospektiven einer absoluten Zeit des Gebens (zB 1000000000000 Sekunden nach dem Urknall). Aber oft müssen wir auch eine bequeme Möglichkeit des Gesprächs, wie ein Objekt einkapseln Jahr, Monat, etc.

Ich frage mich, ob es neue Fortschritte in der Java diese 2 Ziele in Einklang zu bringen. Vielleicht Wissen meines Java ist zu alt.

Btw „Datum“ wird in der Regel als „veraltet / veraltet“ markiert (Ich weiß nicht genau, warum) - etwas dagegen ist es geschrieben Java: Warum wird der Date-Konstruktor veraltet und was verwende ich stattdessen?

Es sieht aus wie es ein Problem des Konstrukteurs ist nur- über Art und Weise new Date (int Jahr, int Monat, int Tag) , Art und Weise empfohlen über Kalender und eingestellt params separat .. ( Kalender cal = Calendar.getInstance (); )

Ich Kalender verwenden, wenn ich einige spezifische Operationen über die Termine müssen wie in der Zeit bewegen, aber seit ich finde es hilfreich, wenn Sie das Datum zu formatieren müssen Ihre Bedürfnisse anpassen, die vor kurzem entdeckte ich, dass Locale viele nützliche Operationen hat und methods.So ich verwende Locale jetzt!

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top