tatsächlich ist getMonth () am Datum seit Ewigkeiten veraltet;)
Mateusz Dymczyk
6
@slhck: Veraltet. Ab JDK Version 1.1, ersetzt durch Calendar.get (Calendar.MONTH).
Adarshr
3
@Zenzen Ich sehe das Problem nicht in der Verwendung einer veralteten Methode in einer meist veralteten Klasse.
Serabe
1
@Muhd Wenn Sie mit Daten arbeiten, helfen Sie sich selbst und verwenden Sie joda oder eine andere Bibliothek.
Serabe
1
@ Serabe: Das Problem ist, dass es bessere Lösungen gibt (solche, die zumindest nicht veraltet sind). Und getMonth ist seit ungefähr 14 Jahren veraltet und aus einem bestimmten Grund veraltet.
Date date =newDate();LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();int month = localDate.getMonthValue();
Beachten Sie, dass hier Monatswerte von 1 bis 12 angegeben werden, im Gegensatz zu cal.get(Calendar.MONTH)adarshrs Antwort, die Werte von 0 bis 11 angibt.
Aber wie Basil Bourque in den Kommentaren sagte, ist der bevorzugte Weg, ein MonthEnum-Objekt mit der LocalDate::getMonthMethode zu erhalten.
Gute Antwort. Hinweis für den Leser: Möglicherweise möchten Sie eine Zeitzone angeben, anstatt sich auf den in der Antwort angegebenen Standardaufruf zu verlassen. Ein neuer Tag (und Monat) bricht beispielsweise in Paris früher an als in Montréal. Wenn Sie sich speziell für Montréal interessieren, ist die Verwendung ZoneId.of( "America/Montreal" ).
Übrigens noch ein Hinweis für den Leser: Sie können auch ein MonthEnum-Objekt anstelle einer bloßen Ganzzahl erhalten. Month m = localDate.gotMonth();Siehe LocalDate::getMonthMethode. Durch die Verwendung solcher Objekte wird Ihr Code selbstdokumentiert, die Typensicherheit gewährleistet und gültige Werte garantiert. Siehe Enum-Tutorial von Oracle.
Basil Bourque
1
Wenn Sie verwenden date.toInstant()und zufällig mit einem java.sql.Date(dem Kind von java.util.Date) arbeiten, erhalten Sie ein UnsupportedOperationException. Versuchen Sienew java.sql.Date(src.getTime()).toLocalDate()
Adam
1
@Adam java.sql.DateMit den neuen Konvertierungsmethoden, die dieser alten Klasse hinzugefügt wurden, ist das Konvertieren viel einfacher . java.sql.Date.valueOf( myLocalDate )und myJavaSqlDate.toLocalDate() auch JDBC - Treiber für JDBC aktualisiert 4.2 oder später nicht mehr brauchen java.sqlTypen und können direkt java.timeAdresstypen über die ResultSet::getObjectund PreparedStatement::setObjectMethoden.
Basil Bourque
287
java.util.Date date=newDate();Calendar cal =Calendar.getInstance();
cal.setTime(date);int month = cal.get(Calendar.MONTH);
Beachten Sie, dass dies Calendar.MONTHohne ersichtlichen Grund NULL-basiert ist, dh Januar == 0. Nun, das ist in der API gut dokumentiert, aber für Erstbenutzer ist es immer noch verdammt verwirrend. Ich habe noch niemanden gefunden, der mir sagen könnte, warum sie so vorgegangen sind - vielleicht selbst Zeit für eine neue SO-Frage (obwohl ich befürchte, dass es dafür keinen großartigen Hintergrund gibt: /)
Voo
5
Die Methode @Voo Date.getMonth () basierte auf Null, was wahrscheinlich auch der Hauptgrund für Calendar.MONTH ist.
Muhd
1
@ Muhd Sicher war es doch der Ersatz. Aber das verschiebt die Frage nur dahin, warum Date.getMonth () auf Null basiert? Ich bin ein schreckliches Design, zumal die Tage um eins beginnen (sie könnten zumindest konsistent sein!). Ich nehme an, es war zunächst nur ein Versehen in einer nicht besonders gut gestalteten API (sowohl Datum als auch Kalender). Aber vielleicht gibt es einen Präzedenzfall - es scheint mir nur seltsam und hat meiner Erfahrung nach mehr als einem Anfänger Probleme bereitet.
Voo
2
Eigentlich wurde es hier schon auf SO gefragt (und nicht nur). Das Endergebnis ist, dass es ein Ergebnis einer schlecht gestalteten API ist. Ich meine, wie du erwähnt hast, ist die ganze Date-Klasse ein Witz. Eine lustige Tatsache ist, dass nicht nur Java unter diesem Problem leidet - das Datum getMonth () von iirc JavaScript beginnt auch mit einer 0!
Mateusz Dymczyk
1
@Voo getYear()wird auch "ohne ersichtliche Gründe" bis 1900 abgezogen.
Hele
17
Wenn Sie Java 8 Date API verwenden, können Sie es direkt in einer Zeile erhalten!
Noch einfacher, fragen Sie einfach das DateTimeObjekt nach seinem Monat. int month = dateTime.getMonthOfYear();
Basil Bourque
Guter Anruf Basil, ich habe den Code aktualisiert. Ich mag das .toString("MM")jedoch, da es mehr Möglichkeiten gibt als nur "MM".
Ssoward
1
Diese Antwort ignoriert das entscheidende Problem der Zeitzone. Siehe meine Kommentare zu Frage und Antwort der Geschwister. Ich schlage vor, ein DateTimeZoneObjekt an diesen DateTime-Konstruktor zu übergeben : DateTimeZone.forID( "America/Montreal" ).
Basil Bourque
6
tl; dr
myUtilDate.toInstant()// Convert from legacy class to modern. `Instant` is a point on the timeline in UTC..atZone(// Adjust from UTC to a particular time zone to determine date. Renders a `ZonedDateTime` object. ZoneId.of("America/Montreal")// Better to specify desired/expected zone explicitly than rely implicitly on the JVM’s current default time zone.)// Returns a `ZonedDateTime` object..getMonthValue()// Extract a month number. Returns a `int` number.
java.time Einzelheiten
Die Antwort von Ortomala Lokni für die Verwendung von java.time ist korrekt. Und Sie sollten java.time verwenden, da dies eine gigantische Verbesserung gegenüber den alten Klassen java.util.Date/.Calendar darstellt. Weitere Informationen finden Sie im Oracle- Lernprogramm auf java.time.
Ich werde Code hinzufügen, der zeigt, wie man java.time ohne Rücksicht auf java.util.Date verwendet, wenn Sie mit neuem Code beginnen.
Verwenden von java.time auf den Punkt gebracht… An Instantist ein Moment auf der Timeline in UTC. Wenden Sie eine Zeitzone ( ZoneId) an, um a zu erhalten ZonedDateTime.
Die MonthKlasse ist eine anspruchsvolle Aufzählung , die einen Monat im Allgemeinen darstellt. Diese Aufzählung enthält praktische Methoden wie das Abrufen eines lokalisierten Namens. Und seien Sie versichert, dass die Monatszahl in java.time eine vernünftige Zahl von 1 bis 12 ist und nicht der auf Null basierende Unsinn (0 bis 11) in java.util.Date/.Calendar.
Um die aktuelle Datums- und Uhrzeitangabe zu erhalten, ist die Zeitzone von entscheidender Bedeutung. Zu jedem Zeitpunkt ist das Datum auf der ganzen Welt nicht dasselbe. Daher ist der Monat weltweit nicht derselbe, wenn er sich dem Ende / Anfang des Monats nähert.
ZoneId zoneId =ZoneId.of("America/Montreal");// Or 'ZoneOffset.UTC'.ZonedDateTime now =ZonedDateTime.now( zoneId );Month month = now.getMonth();int monthNumber = month.getValue();// Answer to the Question.String monthName = month.getDisplayName(TextStyle.FULL ,Locale.CANADA_FRENCH );
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.
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 .
Wenn Sie die Joda-Zeit nicht nutzen können und immer noch in der dunklen Welt leben :) (Java 5 oder niedriger), können Sie dies genießen:
Hinweis: Stellen Sie sicher, dass Ihr Datum bereits im Format TT / MM / JJJJ erstellt wurde
/**
Make an int Month from a date
*/publicstaticint getMonthInt(Date date){SimpleDateFormat dateFormat =newSimpleDateFormat("MM");returnInteger.parseInt(dateFormat.format(date));}/**
Make an int Year from a date
*/publicstaticint getYearInt(Date date){SimpleDateFormat dateFormat =newSimpleDateFormat("yyyy");returnInteger.parseInt(dateFormat.format(date));}
2 Probleme mit Ihrer Antwort: Eines ist, dass Sie ein Datum mit der aktuellen Uhrzeit erstellen können, indem Sie darauf new Date()verzichten System.currentTimeMillis. Das andere ist, dass getMonth veraltet ist.
Muhd
@ Muhd Also, was ist die beste Lösung?
Twlkyao
@Muhd Das System.currentTimeMillis (), das ich hier hinzugefügt habe, sollte anzeigen, dass es sich um einen langen Typ handelt, und Sie können das Datum angeben.
Antworten:
java.time (Java 8)
Sie können auch das Paket java.time in Java 8 verwenden, Ihr
java.util.Date
Objekt in einjava.time.LocalDate
Objekt konvertieren und dann einfach diegetMonthValue()
Methode verwenden.Beachten Sie, dass hier Monatswerte von 1 bis 12 angegeben werden, im Gegensatz zu
cal.get(Calendar.MONTH)
adarshrs Antwort, die Werte von 0 bis 11 angibt.Aber wie Basil Bourque in den Kommentaren sagte, ist der bevorzugte Weg, ein
Month
Enum-Objekt mit derLocalDate::getMonth
Methode zu erhalten.quelle
ZoneId.of( "America/Montreal" )
.Month
Enum-Objekt anstelle einer bloßen Ganzzahl erhalten.Month m = localDate.gotMonth();
SieheLocalDate::getMonth
Methode. Durch die Verwendung solcher Objekte wird Ihr Code selbstdokumentiert, die Typensicherheit gewährleistet und gültige Werte garantiert. Siehe Enum-Tutorial von Oracle.date.toInstant()
und zufällig mit einemjava.sql.Date
(dem Kind vonjava.util.Date
) arbeiten, erhalten Sie einUnsupportedOperationException
. Versuchen Sienew java.sql.Date(src.getTime()).toLocalDate()
java.sql.Date
Mit den neuen Konvertierungsmethoden, die dieser alten Klasse hinzugefügt wurden, ist das Konvertieren viel einfacher .java.sql.Date.valueOf( myLocalDate )
undmyJavaSqlDate.toLocalDate()
auch JDBC - Treiber für JDBC aktualisiert 4.2 oder später nicht mehr brauchenjava.sql
Typen und können direktjava.time
Adresstypen über dieResultSet::getObject
undPreparedStatement::setObject
Methoden.quelle
Calendar.MONTH
ohne ersichtlichen Grund NULL-basiert ist, dh Januar == 0. Nun, das ist in der API gut dokumentiert, aber für Erstbenutzer ist es immer noch verdammt verwirrend. Ich habe noch niemanden gefunden, der mir sagen könnte, warum sie so vorgegangen sind - vielleicht selbst Zeit für eine neue SO-Frage (obwohl ich befürchte, dass es dafür keinen großartigen Hintergrund gibt: /)getYear()
wird auch "ohne ersichtliche Gründe" bis 1900 abgezogen.Wenn Sie Java 8 Date API verwenden, können Sie es direkt in einer Zeile erhalten!
quelle
Joda-Zeit
Alternativ mit der Joda-Time-
DateTime
Klasse.…oder…
quelle
DateTime
Objekt nach seinem Monat.int month = dateTime.getMonthOfYear();
.toString("MM")
jedoch, da es mehr Möglichkeiten gibt als nur "MM".DateTimeZone
Objekt an diesen DateTime-Konstruktor zu übergeben :DateTimeZone.forID( "America/Montreal" )
.tl; dr
java.time
EinzelheitenDie Antwort von Ortomala Lokni für die Verwendung von java.time ist korrekt. Und Sie sollten java.time verwenden, da dies eine gigantische Verbesserung gegenüber den alten Klassen java.util.Date/.Calendar darstellt. Weitere Informationen finden Sie im Oracle- Lernprogramm auf java.time.
Ich werde Code hinzufügen, der zeigt, wie man java.time ohne Rücksicht auf java.util.Date verwendet, wenn Sie mit neuem Code beginnen.
Verwenden von java.time auf den Punkt gebracht… An
Instant
ist ein Moment auf der Timeline in UTC. Wenden Sie eine Zeitzone (ZoneId
) an, um a zu erhaltenZonedDateTime
.Die
Month
Klasse ist eine anspruchsvolle Aufzählung , die einen Monat im Allgemeinen darstellt. Diese Aufzählung enthält praktische Methoden wie das Abrufen eines lokalisierten Namens. Und seien Sie versichert, dass die Monatszahl in java.time eine vernünftige Zahl von 1 bis 12 ist und nicht der auf Null basierende Unsinn (0 bis 11) in java.util.Date/.Calendar.Um die aktuelle Datums- und Uhrzeitangabe zu erhalten, ist die Zeitzone von entscheidender Bedeutung. Zu jedem Zeitpunkt ist das Datum auf der ganzen Welt nicht dasselbe. Daher ist der Monat weltweit nicht derselbe, wenn er sich dem Ende / Anfang des Monats nähert.
Ü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
.Das Joda-Time- Projekt, das sich jetzt im Wartungsmodus befindet , empfiehlt die Migration zu den Klassen java.time .
Weitere Informationen finden Sie im Oracle-Lernprogramm . Suchen Sie im Stapelüberlauf nach vielen Beispielen und Erklärungen. Die Spezifikation ist JSR 310 .
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
Wenn Sie die Joda-Zeit nicht nutzen können und immer noch in der dunklen Welt leben :) (Java 5 oder niedriger), können Sie dies genießen:
Hinweis: Stellen Sie sicher, dass Ihr Datum bereits im Format TT / MM / JJJJ erstellt wurde
quelle
Der zurückgegebene Wert beginnt bei 0, daher sollten Sie dem Ergebnis einen hinzufügen.
quelle
new Date()
verzichtenSystem.currentTimeMillis
. Das andere ist, dass getMonth veraltet ist.