Java: ottieni il numero intero mese dalla data


157

Come posso ottenere il mese come intero da un oggetto Date ( java.util.Date)?


23
effettivamente getMonth () alla data è obsoleto da sempre;)
Mateusz Dymczyk

6
@slhck: obsoleto. A partire dalla versione 1.1 di JDK, sostituita da Calendar.get (Calendar.MONTH).
Adarshr,

3
@Zenzen Non vedo il problema nell'uso di un metodo deprecato in una classe per lo più deprecata.
Serabe,

1
@Muhd se lavori con le date, aiutati e usa joda o qualsiasi altra libreria.
Serabe,

1
@Serabe: il problema è che esistono soluzioni migliori (almeno non deprecate). E getMonth è stato deprecato per circa 14 anni ed è stato deprecato per un motivo.
Mateusz Dymczyk,

Risposte:


57

java.time (Java 8)

Puoi anche usare il pacchetto java.time in Java 8 e convertire il tuo java.util.Dateoggetto in un java.time.LocalDateoggetto e poi semplicemente usare il getMonthValue()metodo.

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

Si noti che i valori del mese sono qui riportati da 1 a 12 contrariamente alla cal.get(Calendar.MONTH)risposta di Adarshr che fornisce valori da 0 a 11.

Ma come ha detto Basil Bourque nei commenti, il modo preferito è ottenere un Monthoggetto enum con il LocalDate::getMonthmetodo.


1
Buona risposta. Nota per il lettore: è possibile che si desideri specificare un fuso orario piuttosto che fare affidamento sulla chiamata per impostazione predefinita mostrata nella risposta. Un nuovo giorno (e mese) sorge prima a Parigi, ad esempio, rispetto a Montréal. Se ti interessa specificamente di Montréal, l'uso ZoneId.of( "America/Montreal" ).
Basil Bourque,

1
Voglio solo aggiungere che c'è un ottimo articolo sull'introduzione di java.time api oracle.com/technetwork/articles/java/…

A proposito, un'altra nota per il lettore: puoi anche ottenere un Monthoggetto enum piuttosto che un semplice numero intero. Month m = localDate.gotMonth();Vedi LocalDate::getMonthmetodo L'utilizzo di oggetti come questo rende il codice auto-documentante, garantisce la sicurezza del tipo e garantisce valori validi. Vedi tutorial Enum di Oracle.
Basil Bourque,

1
se usi date.toInstant()e ti capita di lavorare con un java.sql.Date(figlio di java.util.Date), otterrai un UnsupportedOperationException. Provanew java.sql.Date(src.getTime()).toLocalDate()
Adam

1
@Adam Molto più facile da convertire in / java.sql.Dateda utilizzando i nuovi metodi di conversione aggiunti a quella vecchia classe. java.sql.Date.valueOf( myLocalDate )e myJavaSqlDate.toLocalDate() Inoltre, i driver JDBC aggiornati per JDBC 4.2 o versione successiva non necessitano più di java.sqltipi e possono indirizzare direttamente i java.timetipi tramite i metodi ResultSet::getObjecte PreparedStatement::setObject.
Basil Bourque,

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

166
Si noti che Calendar.MONTHper nessuna ragione apparente è basato su ZERO, ovvero gennaio == 0. Ora questo è documentato bene nell'API, ma è ancora confuso per gli utenti alle prime armi. Devo ancora trovare qualcuno che possa dirmi perché sono andati con quello - forse il tempo per una nuova domanda SO (anche se temo che non ci sia un grande background a questo: /)
Voo

5
Il metodo @Voo Date.getMonth () era basato su zero, che è probabilmente anche il motivo principale per Calendar.MONTH.
Muhd,

1
@Muhd Certo, dopo tutto è stata la sostituzione. Ma questo sposta solo la domanda sul perché Date.getMonth () era basato su zero? Imo un design orribile, soprattutto da quando i giorni iniziano in uno (potrebbero almeno essere coerenti!). Immagino sia stata solo una svista in un'API non particolarmente ben progettata (sia data che calendario) per cominciare. Ma forse c'è un precedente - mi sembra strano e ha causato problemi a più di un principiante nella mia esperienza.
Voo,

2
In realtà è già stato chiesto qui su SO (e non solo). La linea di fondo è che è il risultato di API mal progettate. Voglio dire, come hai detto, l'intera classe Date è uno scherzo. Il fatto divertente è che non solo Java soffre di questo problema, ma iirc JavaScript Date GetMonth () inizia anche con uno 0!
Mateusz Dymczyk,

1
@Voo getYear()è anche, "per nessuna ragione apparente", sottratto dal 1900.
Hele

17

Se usi Java 8 Date API, puoi ottenerlo direttamente in una riga!

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

7

Joda-Time

In alternativa, con la classe Joda-Time DateTime .

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

…o…

int month = dateTime.getMonthOfYear();

2
Ancora più semplice, basta chiedere DateTimeall'oggetto il suo mese. int month = dateTime.getMonthOfYear();
Basil Bourque,

Buona telefonata Basil, ho aggiornato il codice. Tuttavia, mi piace .toString("MM")come mostra che ci sono più possibilità di un semplice "MM".
sabato

1
Questa risposta ignora la questione cruciale del fuso orario. Vedi i miei commenti su domande e risposte di pari livello. Suggerisco passando un DateTimeZoneoggetto a quel costruttore 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 Dettagli

La risposta di Ortomala Lokni per l'utilizzo di java.time è corretta. E dovresti usare java.time in quanto è un enorme miglioramento rispetto alle vecchie classi java.util.Date/.Calendar. Consulta il tutorial Oracle su java.time.

Aggiungerò un po 'di codice che mostra come utilizzare java.time senza riguardo a java.util.Date, per quando inizi con un nuovo codice.

Usando java.time in breve ... An Instantè un momento sulla linea temporale in UTC. Applica un fuso orario ( ZoneId) per ottenere un ZonedDateTime.

La Monthclasse è un enum sofisticato per rappresentare un mese in generale. Quell'enum ha metodi utili come ottenere un nome localizzato. E state certi che il numero del mese in java.time è sano, 1-12, non l'assurdità a base zero (0-11) trovata in java.util.Date/.Calendar.

Per ottenere la data-ora corrente, il fuso orario è cruciale. In qualsiasi momento la data non è la stessa in tutto il mondo. Pertanto il mese non è lo stesso in tutto il mondo se vicino alla fine / all'inizio del mese.

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

Informazioni su java.time

Il framework java.time è integrato in Java 8 e versioni successive. Queste classi soppiantare la vecchia fastidiosi legacy classi data-time come java.util.Date, Calendar, e SimpleDateFormat.

Il progetto Joda-Time , ora in modalità manutenzione , consiglia la migrazione alle classi java.time .

Per saperne di più, consulta il tutorial Oracle . E cerca Stack Overflow per molti esempi e spiegazioni. La specifica è JSR 310 .

Puoi scambiare oggetti java.time direttamente con il tuo database. Utilizzare un driver JDBC conforme a JDBC 4.2 o successivo. Non c'è bisogno di stringhe, non c'è bisogno di java.sql.*classi.

Dove ottenere le classi java.time?

Il progetto ThreeTen-Extra estende java.time con classi aggiuntive. Questo progetto è un banco di prova per possibili aggiunte future a java.time. Si possono trovare alcune classi utili, come per esempio Interval, YearWeek, YearQuartere altro .


4

Se non puoi usare il tempo Joda e vivi ancora nel mondo oscuro :) (Java 5 o inferiore) puoi goderti questo:

Nota: assicurati che la tua data sia già stata creata nel formato: gg / MM / AAAA

/**
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));
}

Tu sei la mamma! / Είσαι η μάνα!
Tzegenos,

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

Il valore restituito inizia da 0, quindi è necessario aggiungerne uno al risultato.


6
2 problemi con la tua risposta: uno è che puoi fare una data con l'ora corrente facendo a new Date()meno System.currentTimeMillis. L'altro è che getMonth è deprecato.
Muhd,

@Muhd Qual è la soluzione migliore?
twlkyao,

@Muhd Il System.currentTimeMillis () che ho aggiunto qui doveva indicare che qui è un tipo lungo e puoi specificare la data.
twlkyao,

4
Data :: getMonth era già obsoleto in Java 1.1 ( cs.mun.ca/~michael/java/jdk1.1-beta2-docs/api/… )
Ortomala Lokni
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.