Perché Java Date.getYear () restituisce 111 anziché 2011?

Sto avendo un po ‘di problemi nell’analizzare una data di stringa su un object Date . Io uso un DateFormat per analizzare la stringa, e quando stampo il valore della data, mi dà quello che mi aspetto.

Ma quando cerco di ottenere il giorno, il mese o l’anno mi danno i valori sbagliati. Ad esempio, l’anno è il 2011, ma quando lo faccio .getYear() mi dà 111. Non ho idea del perché questo stia accadendo. Ecco il segmento di codice pertinente:

  Date dateFrom = null; String gDFString = g.getDateFrom(); System.out.println(gDFString); DateFormat df = new SimpleDateFormat("dd/MM/yyyy"); try { dateFrom = df.parse("04/12/2011"); System.out.println(dateFrom); System.out.println(dateFrom.getYear()); } catch (ParseException e) { e.printStackTrace(); } 

Quando esco dalla data di stampa, ricevo Sun Dec 04 00:00:00 GMT 2011 , che è quello che ti aspetteresti. Ma la stampa .getYear() restituisce 111 .

Devo essere in grado di ottenere il giorno, il mese e l’anno della data per un grafico delle serie temporali.

Quei metodi sono stati deprecati . Invece, usa la class Calendar .


 import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; public final class DateParseDemo { public static void main(String[] args){ final DateFormat df = new SimpleDateFormat("MM/dd/yyyy"); final Calendar c = Calendar.getInstance(); try { c.setTime(df.parse("04/12/2011")); System.out.println("Year = " + c.get(Calendar.YEAR)); System.out.println("Month = " + (c.get(Calendar.MONTH))); System.out.println("Day = " + c.get(Calendar.DAY_OF_MONTH)); } catch (ParseException e) { e.printStackTrace(); } } } 

Uscita :

 Year = 2011 Month = 3 Day = 12 

E per quanto riguarda il campo del mese , questo è basato su 0. Ciò significa che gennaio = 0 e dicembre = 11. Come affermato dalla javadoc ,

Il numero del campo per ottenere e impostare indicando il mese. Questo è un valore specifico del calendario. Il primo mese dell’anno nei calendari gregoriano e giuliano è JANUARY che è 0 ; l’ultimo dipende dal numero di mesi in un anno.

Javadoc in soccorso:

Deprecato. A partire da JDK versione 1.1, sostituito da Calendar.get (Calendar.YEAR) – 1900.

Restituisce un valore che è il risultato della sottrazione di 1900 dell’anno che contiene o inizia con l’istante in tempo rappresentato da questo object Date, come interpretato nel fuso orario locale.

Non dovresti usare metodi deprecati. I metodi deprecati sono metodi che non dovrebbero più essere usati. Qualunque sia il metodo che stai usando, leggi la sua javadoc per sapere cosa fa.

Il presidente Evil l’ha inchiodato, Date.getYear() restituisce un valore che è il risultato della sottrazione di 1900 dell’anno che contiene. E tu non dovresti usarlo.

Ma la soluzione rapida per il codice nella domanda è:

 Date dateFrom = null; String gDFString = g.getDateFrom(); System.out.println(gDFString); DateFormat df = new SimpleDateFormat("dd/MM/yyyy"); try { dateFrom = df.parse("04/12/2011"); System.out.println(dateFrom); // Add 1900 to dateFrom.getYear() System.out.println(dateFrom.getYear()+1900); } catch (ParseException e) { e.printStackTrace(); } 

Questa è solo un’ipotesi, ma il 111 potrebbe essere il numero di anni dal 1900. Dai un’occhiata alla documentazione / fai qualche test per verificarlo (non posso controllare al momento)

http://download.oracle.com/javase/1.4.2/docs/api/java/util/Date.html#getYear%28%29

La specifica afferma che restituisce l’anno meno 1900. Probabilmente è una buona idea evitare anche i metodi deprecati.

tl; dr

 int year = LocalDate.parse( "04/12/2011" , DateTimeFormatter.ofLocalizedDate( FormatStyle.SHORT ).withLocale( Locale.US ) ).getYear() ; 

2011

java.time

La fastidiosa class java.util.Date e i suoi fratelli sono ora soppiantati dalle eccellenti classi java.time.

 String input = "04/12/2011"; Locale locale = Locale.US; DateTimeFormatter f = DateTimeFormatter.ofLocalizedDate( FormatStyle.SHORT ).withLocale( locale ); LocalDate ld = LocalDate.parse( input , f ); 

Le classi java.time utilizzano la numerazione sana, con:

  • Mesi 1-12 per gennaio-dicembre
  • 2011 significa 2011
  • I giorni della settimana sono 1-7 per lunedì-domenica (secondo ISO 8601 ).

Interrogare il LocalDate per le sue parti costituenti.

 int year = ld.getYear(); // 2011 int month = ld.getMonthValue(); // 4 int dayOfMonth = ld.getDayOfMonth(); // 12 

Puoi anche chiedere automaticamente il nome localizzato del mese e il nome del giorno della settimana.

 String monthName = ld.getMonth().getDisplayName( TextStyle.FULL_STANDALONE , Locale.CANDA_FRENCH ); // avril 

A proposito di java.time

Il framework java.time è integrato in Java 8 e versioni successive. Queste classi soppiantano le fastidiose vecchie classi data-time come java.util.Date , .Calendar e & java.text.SimpleDateFormat .

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

Per saperne di più, consultare l’ esercitazione Oracle . E cerca Stack Overflow per molti esempi e spiegazioni.

Gran parte della funzionalità java.time è back-porting su Java 6 e 7 in ThreeTen-Backport e ulteriormente adattata ad Android in ThreeTenABP (vedi Come usare … ).

Il progetto ThreeTen-Extra estende java.time con classi aggiuntive. Questo progetto è un terreno di prova per possibili aggiunte future a java.time. Puoi trovare alcune classi utili come Interval , YearWeek , YearQuarter e altro.