¿Por qué Java Date.getYear () devuelve 111 en lugar de 2011?

Estoy teniendo problemas para analizar una fecha de cadena en un objeto Date . Yo uso un DateFormat para analizar la cadena, y cuando DateFormat el valor de la fecha, me da lo que espero.

Pero cuando bash obtener el día, el mes o el año, me da los valores equivocados. Por ejemplo, el año es 2011, pero cuando lo hago .getYear() me da 111. No tengo idea de por qué sucede esto. Aquí está el segmento de código relevante:

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

Cuando dateFrom , me sale el Sun Dec 04 00:00:00 GMT 2011 , que es lo que se espera. Pero imprimir .getYear() devuelve 111 .

Necesito poder obtener el día, mes y año de la fecha para un gráfico de series temporales.

Esos métodos han sido desaprobados . En su lugar, use la clase Calendario .


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

Salida :

 Year = 2011 Month = 3 Day = 12 

Y en cuanto al campo del mes , esto está basado en 0. Esto significa que enero = 0 y diciembre = 11. Según lo declarado por el javadoc ,

Número de campo para get y set que indica el mes. Este es un valor específico del calendario. El primer mes del año en los calendarios gregoriano y juliano es JANUARY que es 0 ; el último depende de la cantidad de meses en un año.

Javadoc al rescate:

Obsoleto. A partir de la versión 1.1 de JDK, reemplazado por Calendar.get (Calendar.YEAR) – 1900.

Devuelve un valor que es el resultado de restar 1900 del año que contiene o comienza con el instante en el tiempo representado por este objeto Date, según se interpreta en la zona horaria local.

No deberías usar métodos desaprobados. Los métodos obsoletos son métodos que ya no deberían usarse. Pero sea cual sea el método que esté usando, lea su javadoc para saber qué hace.

El presidente Evil lo clavó, Date.getYear() devuelve un valor que es el resultado de restar 1900 del año que contiene. Y tú no deberías usarlo.

Pero una solución rápida para el código en la pregunta es:

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

Esto es solo una suposición, pero el 111 podría ser el número de años desde 1900. Eche un vistazo a la documentación / haga algunas pruebas para verificar esto (no puedo verificarlo en este momento)

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

La especificación indica que devuelve el año menos 1900. Probablemente sea una buena idea evitar también los métodos en desuso.

tl; dr

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

2011

java.time

La problemática clase java.util.Date y sus hermanos ahora son suplantados por las excelentes clases de 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 ); 

Las clases java.time utilizan la numeración correcta, con:

  • Meses 1-12 para enero-diciembre
  • 2011 significa 2011
  • Los días de la semana son 1-7 de lunes a domingo (según ISO 8601 ).

Interrogue LocalDate por sus partes constituyentes.

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

Incluso puede solicitar el nombre automáticamente localizado del mes y el nombre del día de la semana.

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

Acerca de java.time

El marco java.time está integrado en Java 8 y posterior. Estas clases suplantan a las antiguas clases problemáticas de fecha y hora, como java.util.Date , .Calendar y java.text.SimpleDateFormat .

El proyecto Joda-Time , ahora en modo de mantenimiento , aconseja la migración a java.time.

Para obtener más información, consulte el Tutorial de Oracle . Y busque Stack Overflow para obtener muchos ejemplos y explicaciones.

Gran parte de la funcionalidad de java.time se transfiere a Java 6 y 7 en ThreeTen-Backport y se adapta mejor a Android en ThreeTenABP (ver Cómo usar … ).

El proyecto ThreeTen-Extra amplía java.time con clases adicionales. Este proyecto es un terreno de prueba para posibles adiciones futuras a java.time. Puede encontrar algunas clases útiles aquí, como Interval , YearWeek , YearQuarter y más.