faktycznie getMonth () on Date jest przestarzałe od zawsze;)
Mateusz Dymczyk
6
@slhck: wycofane. Od wersji 1.1 JDK zastąpiony przez Calendar.get (Calendar.MONTH).
adarshr
3
@Zenzen Nie widzę problemu w używaniu przestarzałej metody w przeważnie przestarzałej klasie.
Serabe
1
@Muhd, jeśli pracujesz z datami, pomóż sobie i użyj jody lub innej biblioteki.
Serabe
1
@Serabe: problem polega na tym, że istnieją lepsze rozwiązania (takie, które przynajmniej nie są przestarzałe). Funkcja getMonth jest przestarzała od 14 lat i nie bez powodu została wycofana.
Date date =newDate();LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();int month = localDate.getMonthValue();
Zauważ, że wartości miesięcy są tutaj podane od 1 do 12, w przeciwieństwie do cal.get(Calendar.MONTH)odpowiedzi adarshr, która podaje wartości od 0 do 11.
Ale jak powiedział Basil Bourque w komentarzach, preferowanym sposobem jest uzyskanie Monthobiektu enum za pomocą LocalDate::getMonthmetody.
Dobra odpowiedź. Uwaga dla czytelnika: Możesz chcieć określić strefę czasową zamiast polegać na wywołaniu domyślnym pokazanym w odpowiedzi. Na przykład nowy dzień (i miesiąc) wstaje w Paryżu wcześniej niż w Montrealu. Jeśli zależy Ci szczególnie na Montrealu, użyj ZoneId.of( "America/Montreal" ).
Nawiasem mówiąc, kolejna uwaga dla czytelnika: można również uzyskać Monthobiekt wyliczenia zamiast zwykłej liczby całkowitej. Month m = localDate.gotMonth();Zobacz LocalDate::getMonthmetodę. Użycie takich obiektów powoduje, że kod samodokumentuje się, zapewnia bezpieczeństwo typów i gwarantuje prawidłowe wartości. Zobacz samouczek dotyczący Enum firmy Oracle.
Basil Bourque
1
jeśli używasz date.toInstant()i pracujesz z java.sql.Date(dzieckiem java.util.Date), otrzymasz rozszerzenie UnsupportedOperationException. Spróbujnew java.sql.Date(src.getTime()).toLocalDate()
Adam,
1
@Adam Znacznie łatwiejsze do konwersji na / z java.sql.Dateprzy użyciu nowych metod konwersji dodanych do tej starej klasy. java.sql.Date.valueOf( myLocalDate )a myJavaSqlDate.toLocalDate() także zaktualizowane sterowniki JDBC dla JDBC 4.2 lub nowszy nie jest już potrzebna java.sqlrodzajów oraz możliwość bezpośredniego kontaktu z java.timetypów za ResultSet::getObjecti PreparedStatement::setObjectmetody.
Basil Bourque
287
java.util.Date date=newDate();Calendar cal =Calendar.getInstance();
cal.setTime(date);int month = cal.get(Calendar.MONTH);
Zauważ, że Calendar.MONTHbez wyraźnych powodów opiera się na ZERO, tj. Styczeń == 0. Teraz jest to dobrze udokumentowane w API, ale wciąż jest mylące dla początkujących użytkowników. Nie znalazłem jeszcze nikogo, kto mógłby mi powiedzieć, dlaczego poszli na to - może sam czas na nowe pytanie SO (choć obawiam się, że nie ma w tym świetnego tła: /)
Voo
5
Metoda @Voo Date.getMonth () była oparta na zerach, co jest prawdopodobnie głównym powodem, dla którego Calendar.MONTH jest również.
Muhd
1
@Muhd Pewnie, że to była wymiana. Ale to tylko przesuwa pytanie, dlaczego Date.getMonth () był oparty na zero? Imo okropny projekt, zwłaszcza że dni zaczynają się od pierwszego (przynajmniej mogą być spójne!). Zakładam, że na początku było to tylko przeoczenie w niezbyt dobrze zaprojektowanym API (zarówno Data, jak i Kalendarz). Ale może jest jakiś precedens - po prostu wydaje mi się to dziwne i z mojego doświadczenia wynika, że przysporzyło problemów więcej niż jednemu początkującemu.
Voo
2
Właściwie pytano o to już tutaj na SO (i nie tylko). Najważniejsze jest to, że jest to wynikiem źle zaprojektowanego API. To znaczy, jak wspomniałeś, cała klasa randkowa to żart. Zabawne jest to, że nie tylko Java cierpi na ten problem - Date getMonth () iirc również zaczyna się od 0!
Mateusz Dymczyk
1
@Voo getYear()jest również odejmowane „bez wyraźnych powodów” do roku 1900.
Hele,
17
Jeśli korzystasz z api dat Java 8 , możesz je pobrać bezpośrednio w jednej linii!
Jeszcze prościej, po prostu zapytaj DateTimeobiekt o jego miesiąc. int month = dateTime.getMonthOfYear();
Basil Bourque
Dobry telefon Bazyli, zaktualizowałem kod. Jednak podoba mi się to, .toString("MM")ponieważ pokazuje, że możliwości jest więcej niż tylko „MM”.
ssoward
1
Ta odpowiedź pomija kluczową kwestię strefy czasowej. Zobacz moje komentarze na temat pytania i odpowiedzi rodzeństwa. Proponuję przechodzącą DateTimeZoneobiekt do tego konstruktora DateTime: 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 Detale
Odpowiedź Ortomala Lokni dotycząca korzystania z java.time jest poprawna. I powinny być korzystając java.time jak to jest gigantyczna poprawa w stosunku do dawnych klas java.util.Date/.Calendar. Zobacz samouczek Oracle w witrynie java.time.
Dodam kod pokazujący, jak używać java.time bez względu na java.util.Date, gdy zaczynasz od nowego kodu.
Korzystanie z java.time w pigułce… InstantTo moment na osi czasu w UTC. Zastosuj strefę czasową ( ZoneId), aby uzyskać plik ZonedDateTime.
MonthKlasa to wyrafinowana enum do reprezentowania miesiąc w ogóle. To wyliczenie ma przydatne metody, takie jak uzyskanie zlokalizowanej nazwy. Zapewniamy, że numer miesiąca w java.time to rozsądny numer 1-12, a nie bzdury zaczynające się od zera (0-11), które można znaleźć w java.util.Date/.Calendar.
Aby uzyskać aktualną datę i godzinę, kluczowa jest strefa czasowa . W żadnym momencie data nie jest taka sama na całym świecie. Dlatego miesiąc nie jest taki sam na całym świecie, jeśli zbliża się koniec / początek miesiąca.
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 );
Aby dowiedzieć się więcej, zobacz samouczek Oracle . I przeszukaj Stack Overflow, aby znaleźć wiele przykładów i wyjaśnień. Specyfikacja to JSR 310 .
Możesz wymieniać obiekty java.time bezpośrednio ze swoją bazą danych. Użyj sterownika JDBC zgodnego z JDBC 4.2 lub nowszym. Nie ma potrzeby stosowania ciągów ani java.sql.*klas.
Projekt ThreeTen-Extra rozszerza java.time o dodatkowe klasy. Ten projekt jest poligonem doświadczalnym dla ewentualnych przyszłych dodatków do java.time. Można znaleźć kilka przydatnych klas tutaj takie jak Interval, YearWeek, YearQuarter, i więcej .
Jeśli nie możesz wykorzystać czasu Jody, a nadal żyjesz w ciemnym świecie :) (Java 5 lub niższa), możesz cieszyć się tym:
Uwaga: upewnij się, że data jest już wpisana w formacie: dd / MM / RRRR
/**
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 problemy z twoją odpowiedzią: jeden z nich polega na tym, że możesz umówić się na randkę z aktualnym czasem, robiąc new Date()bez System.currentTimeMillis. Po drugie, metoda getMonth jest przestarzała.
Muhd
@Muhd Jakie jest więc najlepsze rozwiązanie?
twlkyao
@Muhd System.currentTimeMillis () dodałem tutaj, aby wskazać, że tutaj jest długi typ i możesz określić datę.
Odpowiedzi:
java.time (Java 8)
Możesz także użyć pakietu java.time w Javie 8 i przekonwertować
java.util.Date
obiekt najava.time.LocalDate
obiekt, a następnie po prostu użyć tejgetMonthValue()
metody.Zauważ, że wartości miesięcy są tutaj podane od 1 do 12, w przeciwieństwie do
cal.get(Calendar.MONTH)
odpowiedzi adarshr, która podaje wartości od 0 do 11.Ale jak powiedział Basil Bourque w komentarzach, preferowanym sposobem jest uzyskanie
Month
obiektu enum za pomocąLocalDate::getMonth
metody.źródło
ZoneId.of( "America/Montreal" )
.Month
obiekt wyliczenia zamiast zwykłej liczby całkowitej.Month m = localDate.gotMonth();
ZobaczLocalDate::getMonth
metodę. Użycie takich obiektów powoduje, że kod samodokumentuje się, zapewnia bezpieczeństwo typów i gwarantuje prawidłowe wartości. Zobacz samouczek dotyczący Enum firmy Oracle.date.toInstant()
i pracujesz zjava.sql.Date
(dzieckiemjava.util.Date
), otrzymasz rozszerzenieUnsupportedOperationException
. Spróbujnew java.sql.Date(src.getTime()).toLocalDate()
java.sql.Date
przy użyciu nowych metod konwersji dodanych do tej starej klasy.java.sql.Date.valueOf( myLocalDate )
amyJavaSqlDate.toLocalDate()
także zaktualizowane sterowniki JDBC dla JDBC 4.2 lub nowszy nie jest już potrzebnajava.sql
rodzajów oraz możliwość bezpośredniego kontaktu zjava.time
typów zaResultSet::getObject
iPreparedStatement::setObject
metody.źródło
Calendar.MONTH
bez wyraźnych powodów opiera się na ZERO, tj. Styczeń == 0. Teraz jest to dobrze udokumentowane w API, ale wciąż jest mylące dla początkujących użytkowników. Nie znalazłem jeszcze nikogo, kto mógłby mi powiedzieć, dlaczego poszli na to - może sam czas na nowe pytanie SO (choć obawiam się, że nie ma w tym świetnego tła: /)getYear()
jest również odejmowane „bez wyraźnych powodów” do roku 1900.Jeśli korzystasz z api dat Java 8 , możesz je pobrać bezpośrednio w jednej linii!
źródło
Joda-Time
Alternatywnie z klasą Joda-Time
DateTime
.…lub…
źródło
DateTime
obiekt o jego miesiąc.int month = dateTime.getMonthOfYear();
.toString("MM")
ponieważ pokazuje, że możliwości jest więcej niż tylko „MM”.DateTimeZone
obiekt do tego konstruktora DateTime:DateTimeZone.forID( "America/Montreal" )
.tl; dr
java.time
DetaleOdpowiedź Ortomala Lokni dotycząca korzystania z java.time jest poprawna. I powinny być korzystając java.time jak to jest gigantyczna poprawa w stosunku do dawnych klas java.util.Date/.Calendar. Zobacz samouczek Oracle w witrynie java.time.
Dodam kod pokazujący, jak używać java.time bez względu na java.util.Date, gdy zaczynasz od nowego kodu.
Korzystanie z java.time w pigułce…
Instant
To moment na osi czasu w UTC. Zastosuj strefę czasową (ZoneId
), aby uzyskać plikZonedDateTime
.Month
Klasa to wyrafinowana enum do reprezentowania miesiąc w ogóle. To wyliczenie ma przydatne metody, takie jak uzyskanie zlokalizowanej nazwy. Zapewniamy, że numer miesiąca w java.time to rozsądny numer 1-12, a nie bzdury zaczynające się od zera (0-11), które można znaleźć w java.util.Date/.Calendar.Aby uzyskać aktualną datę i godzinę, kluczowa jest strefa czasowa . W żadnym momencie data nie jest taka sama na całym świecie. Dlatego miesiąc nie jest taki sam na całym świecie, jeśli zbliża się koniec / początek miesiąca.
Informacje o java.time
Struktura java.time jest wbudowana w Javę 8 i nowsze. Klasy te kłopotliwe zastąpić stary starszych klas Date-Time, takich jak
java.util.Date
,Calendar
, iSimpleDateFormat
.Projekt Joda-Time , obecnie w trybie konserwacji , zaleca migrację do klas java.time .
Aby dowiedzieć się więcej, zobacz samouczek Oracle . I przeszukaj Stack Overflow, aby znaleźć wiele przykładów i wyjaśnień. Specyfikacja to JSR 310 .
Możesz wymieniać obiekty java.time bezpośrednio ze swoją bazą danych. Użyj sterownika JDBC zgodnego z JDBC 4.2 lub nowszym. Nie ma potrzeby stosowania ciągów ani
java.sql.*
klas.Skąd wziąć klasy java.time?
Projekt ThreeTen-Extra rozszerza java.time o dodatkowe klasy. Ten projekt jest poligonem doświadczalnym dla ewentualnych przyszłych dodatków do java.time. Można znaleźć kilka przydatnych klas tutaj takie jak
Interval
,YearWeek
,YearQuarter
, i więcej .źródło
Jeśli nie możesz wykorzystać czasu Jody, a nadal żyjesz w ciemnym świecie :) (Java 5 lub niższa), możesz cieszyć się tym:
Uwaga: upewnij się, że data jest już wpisana w formacie: dd / MM / RRRR
źródło
Zwracana wartość zaczyna się od 0, więc do wyniku należy dodać jeden.
źródło
new Date()
bezSystem.currentTimeMillis
. Po drugie, metoda getMonth jest przestarzała.