sebenarnya getMonth () pada Tanggal sudah usang sejak selamanya;)
Mateusz Dymczyk
6
@ slhck: Sudah usang. Pada JDK versi 1.1, digantikan oleh Calendar.get (Calendar.MONTH).
adarshr
3
@ Zenzen Saya tidak melihat masalah dalam menggunakan metode usang di sebagian besar kelas usang.
Serabe
1
@ Muhd jika Anda bekerja dengan tanggal, membantu diri sendiri dan menggunakan joda atau perpustakaan lainnya.
Serabe
1
@Serabe: masalahnya adalah ada solusi yang lebih baik (yang setidaknya tidak usang). Dan getMonth telah ditinggalkan selama 14 tahun sekarang dan sudah usang karena suatu alasan.
Date date =newDate();LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();int month = localDate.getMonthValue();
Perhatikan bahwa nilai bulan di sini diberikan dari 1 hingga 12 bertentangan dengan cal.get(Calendar.MONTH)jawaban adarshr yang memberikan nilai dari 0 hingga 11.
Tetapi seperti dikatakan Basil Bourque dalam komentar, cara yang lebih disukai adalah mendapatkan Monthobjek enum dengan LocalDate::getMonthmetode tersebut.
Jawaban yang bagus. Catatan untuk pembaca: Anda mungkin ingin menentukan zona waktu daripada mengandalkan panggilan untuk default yang ditunjukkan dalam Jawaban. Misalnya, hari baru (dan bulan) baru saja tiba di Paris, daripada Montréal. Jika Anda peduli secara khusus tentang Montréal, gunakan ZoneId.of( "America/Montreal" ).
By the way, catatan lain untuk pembaca: Anda juga bisa mendapatkan Monthobjek enum daripada bilangan bulat belaka. Month m = localDate.gotMonth();Lihat LocalDate::getMonthmetode. Menggunakan objek seperti ini membuat kode Anda mendokumentasikan diri sendiri, memastikan keamanan jenis, dan menjamin nilai yang valid. Lihat tutorial Enum oleh Oracle.
Basil Bourque
1
jika Anda menggunakan date.toInstant()dan Anda kebetulan bekerja dengan java.sql.Date(anak java.util.Date) maka Anda akan mendapatkan UnsupportedOperationException. Cobanew java.sql.Date(src.getTime()).toLocalDate()
Adam
1
@Adam Jauh lebih mudah untuk mengonversi ke / dari java.sql.Datedengan menggunakan metode konversi baru yang ditambahkan ke kelas lama itu. java.sql.Date.valueOf( myLocalDate )dan myJavaSqlDate.toLocalDate() Juga, driver JDBC yang diperbarui untuk JDBC 4.2 atau yang lebih baru tidak lagi memerlukan java.sqltipe, dan dapat langsung menangani java.timetipe melalui ResultSet::getObjectdan PreparedStatement::setObjectmetode.
Basil Bourque
287
java.util.Date date=newDate();Calendar cal =Calendar.getInstance();
cal.setTime(date);int month = cal.get(Calendar.MONTH);
Perhatikan bahwa Calendar.MONTHtanpa alasan yang jelas ZERO berdasarkan, yaitu Januari == 0. Nah, itu didokumentasikan dengan baik di API, tetapi masih membingungkan bagi pengguna pertama kali. Saya belum menemukan orang yang bisa memberi tahu saya mengapa mereka pergi dengan itu - mungkin waktu untuk pertanyaan SO baru sendiri (meskipun saya khawatir tidak ada latar belakang yang bagus untuk itu: /)
Voo
5
Metode @Voo Date.getMonth () berbasis nol, yang mungkin merupakan alasan utama Calendar.MONTH juga.
Muhd
1
@Muhd Tentu setelah semua itu penggantinya. Tapi itu hanya menggeser pertanyaan sekitar mengapa Date.getMonth () berbasis nol? Imo desain yang mengerikan, terutama sejak hari mulai pada satu (mereka setidaknya bisa konsisten!). Saya berasumsi itu hanya beberapa pengawasan dalam API yang tidak dirancang dengan baik (Tanggal dan Kalender) untuk memulai. Tapi mungkin ada beberapa preseden - sepertinya aneh bagi saya dan telah menyebabkan masalah lebih dari satu pemula dalam pengalaman saya.
Voo
2
Sebenarnya sudah diminta sudah di sini di SO (dan tidak hanya). Intinya adalah bahwa ini adalah hasil dari API yang dirancang dengan buruk. Maksud saya saat Anda menyebutkan seluruh kelas Date adalah lelucon. Fakta yang menyenangkan adalah bahwa tidak hanya Java yang menderita masalah ini - Date getMonth iirc JavaScript juga dimulai dengan 0!
Mateusz Dymczyk
1
@Vo getYear()juga, "tanpa alasan yang jelas", dikurangi pada tahun 1900.
Hele
17
Jika Anda menggunakan Java 8 date api, Anda dapat langsung mendapatkannya dalam satu baris!
Lebih sederhana lagi, tanyakan saja bulan berapa DateTimebulan. int month = dateTime.getMonthOfYear();
Basil Bourque
Good call Basil, saya telah memperbarui kodenya. Namun, saya suka .toString("MM")karena itu menunjukkan ada lebih banyak kemungkinan daripada hanya "MM".
ssoward
1
Jawaban ini mengabaikan masalah krusial zona waktu. Lihat komentar saya pada Pertanyaan dan Jawaban saudara. Saya sarankan melewati DateTimeZoneobjek untuk yang DateTime konstruktor: 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 Detail
Jawaban oleh Ortomala Lokni untuk menggunakan java.time sudah benar. Dan Anda harus menggunakan java.time karena ini merupakan peningkatan besar atas kelas java.util.Date/.Calendar lama. Lihat Tutorial Oracle di java.time.
Saya akan menambahkan beberapa kode yang menunjukkan cara menggunakan java.time tanpa memperhatikan java.util.Date, untuk saat Anda memulai dengan kode baru.
Singkatnya, menggunakan java.time ... An Instantadalah saat di timeline di UTC. Terapkan zona waktu ( ZoneId) untuk mendapatkan aZonedDateTime .
The Monthkelas canggih enum untuk mewakili bulan pada umumnya. Enum itu memiliki metode praktis seperti mendapatkan nama yang dilokalkan. Dan yakinlah bahwa jumlah bulan di java.time adalah yang waras, 1-12, bukan omong kosong berbasis nol (0-11) yang ditemukan di java.util.Date/.Calendar.
Untuk mendapatkan tanggal-waktu saat ini, zona waktu sangat penting. Setiap saat, tanggalnya tidak sama di seluruh dunia. Karena itu bulannya tidak sama di seluruh dunia jika mendekati akhir / awal bulan.
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 );
Untuk mempelajari lebih lanjut, lihat Tutorial Oracle . Dan cari Stack Overflow untuk banyak contoh dan penjelasan. Spesifikasi adalah JSR 310 .
Anda dapat bertukar objek java.time secara langsung dengan database Anda. Gunakan driver JDBC yang sesuai dengan JDBC 4.2 atau yang lebih baru. Tidak perlu untuk string, tidak perlujava.sql.* kelas.
Proyek ThreeTen-Extra memperpanjang java.time dengan kelas tambahan. Proyek ini adalah ajang pembuktian untuk kemungkinan penambahan masa depan ke java.time. Anda mungkin menemukan beberapa kelas berguna di sini seperti Interval, YearWeek, YearQuarter, dan lebih .
Jika Anda tidak dapat menggunakan waktu Joda dan Anda masih hidup di dunia yang gelap :) (Java 5 atau lebih rendah) Anda dapat menikmati ini:
Catatan: Pastikan tanggal Anda sudah dibuat dengan format: dd / MM / YYYY
/**
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 masalah dengan jawaban Anda: satu adalah bahwa Anda dapat membuat kencan dengan waktu saat ini dengan melakukan new Date()tanpa System.currentTimeMillis. Yang lainnya adalah getMonth sudah tidak digunakan lagi.
Muhd
@ Muhd Jadi apa solusi terbaik?
twlkyao
@ Muhd The System.currentTimeMillis () yang saya tambahkan di sini adalah untuk menunjukkan bahwa ini adalah tipe yang panjang, dan Anda dapat menentukan tanggalnya.
Jawaban:
java.time (Java 8)
Anda juga dapat menggunakan paket java.time di Java 8 dan mengonversi
java.util.Date
objek Anda menjadijava.time.LocalDate
objek dan kemudian cukup menggunakangetMonthValue()
metode ini.Perhatikan bahwa nilai bulan di sini diberikan dari 1 hingga 12 bertentangan dengan
cal.get(Calendar.MONTH)
jawaban adarshr yang memberikan nilai dari 0 hingga 11.Tetapi seperti dikatakan Basil Bourque dalam komentar, cara yang lebih disukai adalah mendapatkan
Month
objek enum denganLocalDate::getMonth
metode tersebut.sumber
ZoneId.of( "America/Montreal" )
.Month
objek enum daripada bilangan bulat belaka.Month m = localDate.gotMonth();
LihatLocalDate::getMonth
metode. Menggunakan objek seperti ini membuat kode Anda mendokumentasikan diri sendiri, memastikan keamanan jenis, dan menjamin nilai yang valid. Lihat tutorial Enum oleh Oracle.date.toInstant()
dan Anda kebetulan bekerja denganjava.sql.Date
(anakjava.util.Date
) maka Anda akan mendapatkanUnsupportedOperationException
. Cobanew java.sql.Date(src.getTime()).toLocalDate()
java.sql.Date
dengan menggunakan metode konversi baru yang ditambahkan ke kelas lama itu.java.sql.Date.valueOf( myLocalDate )
danmyJavaSqlDate.toLocalDate()
Juga, driver JDBC yang diperbarui untuk JDBC 4.2 atau yang lebih baru tidak lagi memerlukanjava.sql
tipe, dan dapat langsung menanganijava.time
tipe melaluiResultSet::getObject
danPreparedStatement::setObject
metode.sumber
Calendar.MONTH
tanpa alasan yang jelas ZERO berdasarkan, yaitu Januari == 0. Nah, itu didokumentasikan dengan baik di API, tetapi masih membingungkan bagi pengguna pertama kali. Saya belum menemukan orang yang bisa memberi tahu saya mengapa mereka pergi dengan itu - mungkin waktu untuk pertanyaan SO baru sendiri (meskipun saya khawatir tidak ada latar belakang yang bagus untuk itu: /)getYear()
juga, "tanpa alasan yang jelas", dikurangi pada tahun 1900.Jika Anda menggunakan Java 8 date api, Anda dapat langsung mendapatkannya dalam satu baris!
sumber
Joda-Time
Atau, dengan kelas Joda-Time
DateTime
.…atau…
sumber
DateTime
bulan.int month = dateTime.getMonthOfYear();
.toString("MM")
karena itu menunjukkan ada lebih banyak kemungkinan daripada hanya "MM".DateTimeZone
objek untuk yang DateTime konstruktor:DateTimeZone.forID( "America/Montreal" )
.tl; dr
java.time
DetailJawaban oleh Ortomala Lokni untuk menggunakan java.time sudah benar. Dan Anda harus menggunakan java.time karena ini merupakan peningkatan besar atas kelas java.util.Date/.Calendar lama. Lihat Tutorial Oracle di java.time.
Saya akan menambahkan beberapa kode yang menunjukkan cara menggunakan java.time tanpa memperhatikan java.util.Date, untuk saat Anda memulai dengan kode baru.
Singkatnya, menggunakan java.time ... An
Instant
adalah saat di timeline di UTC. Terapkan zona waktu (ZoneId
) untuk mendapatkan aZonedDateTime
.The
Month
kelas canggih enum untuk mewakili bulan pada umumnya. Enum itu memiliki metode praktis seperti mendapatkan nama yang dilokalkan. Dan yakinlah bahwa jumlah bulan di java.time adalah yang waras, 1-12, bukan omong kosong berbasis nol (0-11) yang ditemukan di java.util.Date/.Calendar.Untuk mendapatkan tanggal-waktu saat ini, zona waktu sangat penting. Setiap saat, tanggalnya tidak sama di seluruh dunia. Karena itu bulannya tidak sama di seluruh dunia jika mendekati akhir / awal bulan.
Tentang java.time
The java.time kerangka dibangun ke Jawa 8 dan kemudian. Kelas-kelas ini menggantikan tua merepotkan warisan kelas tanggal-waktu seperti
java.util.Date
,Calendar
, &SimpleDateFormat
.Proyek Joda-Time , sekarang dalam mode pemeliharaan , menyarankan migrasi ke kelas java.time .
Untuk mempelajari lebih lanjut, lihat Tutorial Oracle . Dan cari Stack Overflow untuk banyak contoh dan penjelasan. Spesifikasi adalah JSR 310 .
Anda dapat bertukar objek java.time secara langsung dengan database Anda. Gunakan driver JDBC yang sesuai dengan JDBC 4.2 atau yang lebih baru. Tidak perlu untuk string, tidak perlu
java.sql.*
kelas.Di mana mendapatkan kelas java.time?
Proyek ThreeTen-Extra memperpanjang java.time dengan kelas tambahan. Proyek ini adalah ajang pembuktian untuk kemungkinan penambahan masa depan ke java.time. Anda mungkin menemukan beberapa kelas berguna di sini seperti
Interval
,YearWeek
,YearQuarter
, dan lebih .sumber
Jika Anda tidak dapat menggunakan waktu Joda dan Anda masih hidup di dunia yang gelap :) (Java 5 atau lebih rendah) Anda dapat menikmati ini:
Catatan: Pastikan tanggal Anda sudah dibuat dengan format: dd / MM / YYYY
sumber
Nilai yang dikembalikan dimulai dari 0, jadi Anda harus menambahkannya ke hasilnya.
sumber
new Date()
tanpaSystem.currentTimeMillis
. Yang lainnya adalah getMonth sudah tidak digunakan lagi.