Java: Tarihten ay Tam Sayı alın


158

Bir Date nesnesinden ( java.util.Date) tamsayı olarak ayı nasıl alabilirim ?


24
aslında getMonth ()
Tarihte

6
@slhck: Onaylanmadı. JDK sürüm 1.1'den itibaren, Calendar.get (Calendar.MONTH) ile değiştirildi.
adarshr

3
@Zenzen Çoğunlukla kullanımdan kaldırılmış bir sınıfta kullanımdan kaldırılmış bir yöntemi kullanmada sorun görmüyorum.
Serabe

1
@Muhd tarihlerle çalışıyorsanız, kendinize yardım edin ve joda ya da başka bir kütüphane kullanın.
Serabe

1
@Serabe: sorun şu ki daha iyi çözümler (en azından kullanımdan kaldırılmamış çözümler). Ve getMonth 14 yıldır kullanımdan kaldırıldı ve bir nedenle kullanımdan kaldırıldı.
Mateusz Dymczyk

Yanıtlar:


58

java.time (Java 8)

Java 8'deki java.time paketini kullanabilir ve nesnenizijava.util.Date bir java.time.LocalDatenesneye dönüştürebilir ve sonra getMonthValue()yöntemi kullanabilirsiniz .

Date date = new Date();
LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
int month = localDate.getMonthValue();

Burada ay değerlerinin cal.get(Calendar.MONTH)adarshr cevabının aksine 1 ila 12 arasında verildiğini ve bu da 0 ila 11 arasında değerler verdiğini unutmayın.

Ancak Basil Bourque'ın yorumlarda söylediği gibi, tercih edilen yöntem yöntemle bir Monthenum nesnesi elde etmektir LocalDate::getMonth.


1
İyi cevap. Okuyucuya not: Cevapta gösterilen varsayılan çağrıya güvenmek yerine bir saat dilimi belirtmek isteyebilirsiniz. Paris'te yeni bir gün (ve ay), Montréal'den daha erken başlar. Özellikle Montréal ile ilgileniyorsanız, kullanın ZoneId.of( "America/Montreal" ).
Basil Bourque


Bu arada, okuyucuya başka bir not: Sadece bir tamsayı numarası yerine bir Monthenum nesnesi de alabilirsiniz . Month m = localDate.gotMonth();Bkz. LocalDate::getMonthYöntem. Bunun gibi nesnelerin kullanılması, kodunuzun kendi kendini belgelemesini sağlar, tip güvenliği sağlar ve geçerli değerleri garanti eder. Oracle'ın Enum öğreticisine bakın .
Basil Bourque

1
kullanırsanız date.toInstant()ve java.sql.Date(çocuğuyla java.util.Date) birlikte çalışıyorsanız o zaman bir UnsupportedOperationException. Deneyinnew java.sql.Date(src.getTime()).toLocalDate()
Adam

1
@Adam java.sql.DateEski sınıfa eklenen yeni dönüştürme yöntemlerini kullanarak / dönüştürmek çok daha kolay . java.sql.Date.valueOf( myLocalDate )ve myJavaSqlDate.toLocalDate() Ayrıca JDBC sürücüleri JDBC 4.2 için güncellenmiş ya da geç artık ihtiyaç java.sqltürleri ve can doğrudan adres java.timetipleri aracılığıyla ResultSet::getObjectve PreparedStatement::setObjectyöntemler.
Basil Bourque

287
java.util.Date date= new Date();
Calendar cal = Calendar.getInstance();
cal.setTime(date);
int month = cal.get(Calendar.MONTH);

166
Bunun Calendar.MONTHZERO tabanlı hiçbir belirgin nedeni olmadığını, yani Ocak == 0 olduğunu unutmayın. Şimdi bu API'da gayet iyi belgelenmiş, ancak ilk kez kullananlar için hala kafa karıştırıcı. Bana neden bununla gittiğini söyleyebilecek birini bulamadım - belki de kendim için yeni bir SO sorusu zamanı (bunun için büyük bir arka plan olmadığından korkuyorum: /)
Voo

5
@Voo Date.getMonth () yöntemi, sıfır tabanlıydı ve bu da Calendar.MONTH öğesinin de ana nedenidir.
Muhd

1
@Muhd Tabii ki yerine geçti. Ancak bu sadece soruyu Date.getMonth () neden sıfır temeline kaydırır? Özellikle günler birinde başladığından beri korkunç bir tasarım Imo (en azından tutarlı olabilirler!). Başlamak için özellikle iyi tasarlanmış bir API'de (hem Tarih hem de Takvim) sadece bir gözetim olduğunu varsayıyorum. Ama belki bir emsal var - benim için sadece garip görünüyor ve tecrübemde birden fazla acemi için sorunlara neden oldu.
Voo

2
Aslında zaten burada SO (ve sadece) üzerinde istendi. Sonuç olarak kötü tasarlanmış API'nin bir sonucudur. Demek istediğim, Date sınıfının tamamı bir şaka. Eğlenceli gerçek şu ki sadece Java bu sorundan muzdarip değil - iirc JavaScript'in Date getMonth () de 0 ile başlar!
Mateusz Dymczyk

1
@Voo getYear()da, "hiçbir belirgin nedenden ötürü", 1900 tarafından çıkarıldı.
Hele

17

Eğer kullanırsanız Java 8 tarih api, doğrudan bir satırda alabilirsiniz!

LocalDate today = LocalDate.now();
int month = today.getMonthValue();

7

Joda-Time

Alternatif olarak, Joda-Time DateTime sınıfıyla.

//convert date to datetime
DateTime datetime = new DateTime(date);
int month = Integer.parseInt(datetime.toString("MM"))

…veya…

int month = dateTime.getMonthOfYear();

2
Daha da basit, sadece DateTimenesnenin ayını isteyin . int month = dateTime.getMonthOfYear();
Basil Bourque

İyi arama Basil, kodu güncelledim. Ancak, .toString("MM")gösterdiği gibi sadece "MM" den daha fazla olasılık var.
ssoward

1
Bu cevap, zaman diliminin önemli meselesini görmezden geliyor. Soru ve kardeş Cevap hakkındaki yorumlarıma bakın. Ben geçen önermek DateTimeZoneo DateTime yapıcı nesneyi: 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 ayrıntılar

Cevap kullanmak için Ortomala Lokni tarafından java.time doğrudur. Ve gerektiğini eski java.util.Date/.Calendar sınıflar üzerinde dev bir gelişme olarak java.time kullanıyor. Java.time ile ilgili Oracle Tutorial'a bakın .

Yeni kodla başladığınızda, java.util.Date'e bakmadan java.time'ın nasıl kullanılacağını gösteren bazı kodlar ekleyeceğim.

Özetle java.time kullanma… An Instant, UTC'de zaman çizelgesinde geçen bir andır. Almak için bir saat dilimi ( ZoneId) uygulayın ZonedDateTime.

MonthSınıf bir sofistike enum genel olarak bir ay temsil etmek. Bu numaralandırma yerelleştirilmiş bir ad alma gibi kullanışlı yöntemlere sahiptir. Ve java.time içindeki ay numarasının, java.util.Date/.Calendar içinde bulunan sıfır tabanlı saçmalık (0-11) değil, 1-12 aklı başında olduğundan emin olun.

Geçerli tarih-saati almak için saat dilimi çok önemlidir. Her an, tarih dünyanın her yerinde aynı değildir . Bu nedenle, ayın sonuna / başlangıcına yakınsa, ay dünya çapında aynı değildir.

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 );

Hakkında java.time

Java.time çerçevesi daha sonra Java 8 ve yerleşiktir. Bu sınıflar zahmetli eski yerini mirası gibi tarih-saat sınıfları java.util.Date, Calendar& SimpleDateFormat.

Artık bakım modunda olan Joda-Time projesi java.time sınıflarına geçişi tavsiye ediyor .

Daha fazla bilgi için Oracle Eğiticisine bakın . Ve birçok örnek ve açıklama için Stack Overflow'da arama yapın. Spesifikasyon JSR 310'dur .

Sen değiştirebilir java.time sizin veritabanı ile doğrudan nesneleri. JDBC 4.2 veya sonraki bir sürümüyle uyumlu bir JDBC sürücüsü kullanın . Dizeye gerek yok, sınıflara gerek yok .java.sql.*

Java.time sınıflarını nereden edinebilirsiniz?

ThreeTen-Ekstra proje ek sınıfları ile java.time uzanır. Bu proje, java.time'a gelecekteki olası eklemeler için bir kanıt zeminidir. Burada bazı yararlı sınıfları gibi bulabilir Interval, YearWeek, YearQuarter, ve daha .


4

Joda zamanını kullanamıyorsanız ve hala karanlık dünyada yaşıyorsanız :) (Java 5 veya daha düşük) bunun keyfini çıkarabilirsiniz:

Not: Tarihinizin zaten şu biçimde olduğundan emin olun: gg / AA / YYYY

/**
Make an int Month from a date
*/
public static int getMonthInt(Date date) {

    SimpleDateFormat dateFormat = new SimpleDateFormat("MM");
    return Integer.parseInt(dateFormat.format(date));
}

/**
Make an int Year from a date
*/
public static int getYearInt(Date date) {

    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy");
    return Integer.parseInt(dateFormat.format(date));
}

Sen annesin! / Είσαι η μάνα!
Tzegenos

0
Date mDate = new Date(System.currentTimeMillis());
mDate.getMonth() + 1

Döndürülen değer 0'dan başlar, bu nedenle sonuca bir tane eklemeniz gerekir.


6
Cevabınızla ilgili 2 sorun: bir tanesi, şimdiki zamanınız new Date()olmadan bir tarih yapabilirsiniz System.currentTimeMillis. Diğeri getMonth'un kullanımdan kaldırılmasıdır.
Muhd

@Muhd Peki en iyi çözüm nedir?
twlkyao

@Muhd Buraya eklediğim System.currentTimeMillis (), burada uzun bir tür olduğunu belirtmekti ve tarihi belirtebilirsiniz.
twlkyao

4
Tarih :: getMonth, Java 1.1'de zaten kullanımdan kaldırıldı ( cs.mun.ca/~michael/java/jdk1.1-beta2-docs/api/… )
Ortomala Lokni
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.