realmente getMonth () na Data está obsoleto desde sempre;)
Mateusz Dymczyk
6
@slhck: descontinuado. A partir do JDK versão 1.1, substituído por Calendar.get (Calendar.MONTH).
adarshr
3
@Zenzen Não vejo o problema de usar um método obsoleto em uma classe principalmente obsoleta.
Serabe 24/08
1
@ Muhd, se você estiver trabalhando com datas, sirva-se e use joda ou qualquer outra biblioteca.
Serabe
1
@ Serabe: o problema é que existem soluções melhores (aquelas que pelo menos não são obsoletas). E o getMonth está obsoleto há 14 anos e está obsoleto por um motivo.
Boa resposta. Nota para o leitor: Você pode especificar um fuso horário em vez de confiar na chamada para o padrão mostrado na resposta. Um novo dia (e mês) amanhece mais cedo em Paris, por exemplo, do que em Montreal. Se você se preocupa especificamente com Montreal, use ZoneId.of( "America/Montreal" ).
A propósito, outra observação para o leitor: Você também pode obter um Monthobjeto enum em vez de um mero número inteiro. Month m = localDate.gotMonth();Veja o LocalDate::getMonthmétodo O uso de objetos como esse torna seu código auto-documentado, garante a segurança do tipo e garante valores válidos. Consulte o tutorial do Enum da Oracle.
Basil Bourque
1
se você usar date.toInstant()e estiver trabalhando com um java.sql.Date(filho de java.util.Date), receberá um UnsupportedOperationException. Tentenew java.sql.Date(src.getTime()).toLocalDate()
Adam
1
@ Adam Muito mais fácil de converter de / para java.sql.Dateusando os novos métodos de conversão adicionados à classe antiga. java.sql.Date.valueOf( myLocalDate )e myJavaSqlDate.toLocalDate() Além disso, os drivers JDBC atualizados para o JDBC 4.2 ou posterior não precisam mais de java.sqltipos e podem endereçar java.timetipos diretamente pelos métodos ResultSet::getObjecte PreparedStatement::setObject.
Basil Bourque 23/03
287
java.util.Date date=newDate();Calendar cal =Calendar.getInstance();
cal.setTime(date);int month = cal.get(Calendar.MONTH);
Observe que, Calendar.MONTHsem motivos aparentes, é baseado em ZERO, ou seja, janeiro == 0. Agora isso está bem documentado na API, mas ainda é confuso para os usuários iniciantes. Ainda estou para encontrar alguém que possa me dizer por que eles concordaram com isso - talvez seja o momento de fazer uma nova pergunta para o SO (embora eu tenha medo de que não exista uma grande base para isso: /) #
Voo
5
O método @Voo Date.getMonth () foi baseado em zero, provavelmente o principal motivo de Calendar.MONTH.
Muhd
1
@ Muhd Claro, afinal, foi a substituição. Mas isso muda apenas a questão de por que o Date.getMonth () foi baseado em zero? Imo um design horrível, especialmente porque os dias começam em um (eles poderiam pelo menos ser consistentes!). Suponho que foi apenas uma supervisão em uma API não especialmente bem projetada (Data e Calendário) para começar. Mas talvez haja algum precedente - isso me parece estranho e causou problemas a mais de um iniciante na minha experiência.
Voo 24/08
2
Na verdade, já foi perguntado aqui no SO (e não apenas). O resultado final é que é resultado de uma API mal projetada. Quero dizer, como você mencionou, toda a classe Date é uma piada. O fato interessante é que não apenas o Java sofre com esse problema - a data getMonth () do JavaScript do iirc também começa com um 0!
Mateusz Dymczyk
1
@Voo getYear()também é "sem razões aparentes", subtraídos por 1900.
Hele
17
Se você usa o Java 8 date api, pode obtê-lo diretamente em uma linha!
Ainda mais simples, basta perguntar ao DateTimeobjeto pelo seu mês. int month = dateTime.getMonthOfYear();
Basil Bourque 28/07
Boa chamada Basil, eu atualizei o código. No entanto, eu gosto do .toString("MM")que mostra, existem mais possibilidades do que apenas "MM".
31814 ssoward
1
Essa resposta ignora a questão crucial do fuso horário. Veja meus comentários na pergunta e na resposta do irmão. Sugiro passando um DateTimeZoneobjeto para que o construtor 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 Detalhes
A resposta de Ortomala Lokni para o uso de java.time está correta. E você deve usar o java.time, pois é uma melhoria gigantesca em relação às antigas classes java.util.Date/.Calendar. Veja o Tutorial do Oracle em java.time.
Vou adicionar um código que mostra como usar o java.time sem considerar o java.util.Date, para quando você estiver iniciando com um novo código.
Usando java.time em poucas palavras… An Instanté um momento na linha do tempo no UTC. Aplique um fuso horário ( ZoneId) para obter umZonedDateTime .
A Monthclasse é uma enumeração sofisticada para representar um mês em geral. Essa enumeração tem métodos úteis, como obter um nome localizado. E tenha certeza de que o número do mês em java.time é sensato, 1 a 12, não o absurdo com base em zero (0 a 11) encontrado em java.util.Date/.Calendar.
Para obter a data e hora atuais, o fuso horário é crucial. A qualquer momento, a data não é a mesma em todo o mundo. Portanto, o mês não é o mesmo em todo o mundo se estiver perto do final / início do mês.
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 );
Para saber mais, consulte o Tutorial do Oracle . E procure Stack Overflow para muitos exemplos e explicações. A especificação é JSR 310 .
Você pode trocar objetos java.time diretamente com seu banco de dados. Use um driver JDBC compatível com JDBC 4.2 ou posterior. Não há necessidade de strings, não há necessidade dejava.sql.* classes.
O projeto ThreeTen-Extra estende java.time com classes adicionais. Este projeto é um campo de prova para possíveis adições futuras ao java.time. Você pode encontrar algumas classes úteis aqui, como Interval, YearWeek, YearQuarter, e mais .
Se você não pode usar o tempo Joda e ainda vive no mundo sombrio :) (Java 5 ou inferior), pode aproveitar o seguinte:
Nota: verifique se a data já foi criada pelo formato: dd / MM / AAAA
/**
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 problemas com a sua resposta: um é que você pode marcar uma data com a hora atual, new Date()sem fazer isso System.currentTimeMillis. A outra é que getMonth está obsoleto.
Muhd
@ Muhd Então, qual é a melhor solução?
Twlkyao 14/05
@Muhd O System.currentTimeMillis () que eu adicionei aqui foi para indicar que aqui é um tipo longo, e você pode especificar a data.
Respostas:
java.time (Java 8)
Você também pode usar o pacote java.time no Java 8 e converter seu
java.util.Date
objeto em umjava.time.LocalDate
objeto e, em seguida, basta usar ogetMonthValue()
métodoObserve que os valores do mês são dados aqui de 1 a 12, ao contrário
cal.get(Calendar.MONTH)
da resposta de adarshr, que fornece valores de 0 a 11.Mas, como Basil Bourque disse nos comentários, a maneira preferida é obter um
Month
objeto enum com oLocalDate::getMonth
método.fonte
ZoneId.of( "America/Montreal" )
.Month
objeto enum em vez de um mero número inteiro.Month m = localDate.gotMonth();
Veja oLocalDate::getMonth
método O uso de objetos como esse torna seu código auto-documentado, garante a segurança do tipo e garante valores válidos. Consulte o tutorial do Enum da Oracle.date.toInstant()
e estiver trabalhando com umjava.sql.Date
(filho dejava.util.Date
), receberá umUnsupportedOperationException
. Tentenew java.sql.Date(src.getTime()).toLocalDate()
java.sql.Date
usando os novos métodos de conversão adicionados à classe antiga.java.sql.Date.valueOf( myLocalDate )
emyJavaSqlDate.toLocalDate()
Além disso, os drivers JDBC atualizados para o JDBC 4.2 ou posterior não precisam mais dejava.sql
tipos e podem endereçarjava.time
tipos diretamente pelos métodosResultSet::getObject
ePreparedStatement::setObject
.fonte
Calendar.MONTH
sem motivos aparentes, é baseado em ZERO, ou seja, janeiro == 0. Agora isso está bem documentado na API, mas ainda é confuso para os usuários iniciantes. Ainda estou para encontrar alguém que possa me dizer por que eles concordaram com isso - talvez seja o momento de fazer uma nova pergunta para o SO (embora eu tenha medo de que não exista uma grande base para isso: /) #getYear()
também é "sem razões aparentes", subtraídos por 1900.Se você usa o Java 8 date api, pode obtê-lo diretamente em uma linha!
fonte
Joda-Time
Como alternativa, com a classe Joda-Time
DateTime
.…ou…
fonte
DateTime
objeto pelo seu mês.int month = dateTime.getMonthOfYear();
.toString("MM")
que mostra, existem mais possibilidades do que apenas "MM".DateTimeZone
objeto para que o construtor DateTime:DateTimeZone.forID( "America/Montreal" )
.tl; dr
java.time
DetalhesA resposta de Ortomala Lokni para o uso de java.time está correta. E você deve usar o java.time, pois é uma melhoria gigantesca em relação às antigas classes java.util.Date/.Calendar. Veja o Tutorial do Oracle em java.time.
Vou adicionar um código que mostra como usar o java.time sem considerar o java.util.Date, para quando você estiver iniciando com um novo código.
Usando java.time em poucas palavras… An
Instant
é um momento na linha do tempo no UTC. Aplique um fuso horário (ZoneId
) para obter umZonedDateTime
.A
Month
classe é uma enumeração sofisticada para representar um mês em geral. Essa enumeração tem métodos úteis, como obter um nome localizado. E tenha certeza de que o número do mês em java.time é sensato, 1 a 12, não o absurdo com base em zero (0 a 11) encontrado em java.util.Date/.Calendar.Para obter a data e hora atuais, o fuso horário é crucial. A qualquer momento, a data não é a mesma em todo o mundo. Portanto, o mês não é o mesmo em todo o mundo se estiver perto do final / início do mês.
Sobre java.time
o estrutura java.time é integrada ao Java 8 e posterior. Essas classes suplantar os velhos problemáticos legados aulas de data e hora, como
java.util.Date
,Calendar
, eSimpleDateFormat
.O projeto Joda-Time , agora em modo de manutenção , aconselha a migração para as classes java.time .
Para saber mais, consulte o Tutorial do Oracle . E procure Stack Overflow para muitos exemplos e explicações. A especificação é JSR 310 .
Você pode trocar objetos java.time diretamente com seu banco de dados. Use um driver JDBC compatível com JDBC 4.2 ou posterior. Não há necessidade de strings, não há necessidade de
java.sql.*
classes.Onde obter as classes java.time?
O projeto ThreeTen-Extra estende java.time com classes adicionais. Este projeto é um campo de prova para possíveis adições futuras ao java.time. Você pode encontrar algumas classes úteis aqui, como
Interval
,YearWeek
,YearQuarter
, e mais .fonte
Se você não pode usar o tempo Joda e ainda vive no mundo sombrio :) (Java 5 ou inferior), pode aproveitar o seguinte:
Nota: verifique se a data já foi criada pelo formato: dd / MM / AAAA
fonte
O valor retornado começa em 0, então você deve adicionar um ao resultado.
fonte
new Date()
sem fazer issoSystem.currentTimeMillis
. A outra é que getMonth está obsoleto.