2012-02-11 17 views
35

Tengo el siguiente problema en Java (Veo algunas personas están teniendo un problema similar en JavaScript, pero estoy usando Java)java.util.Date y GetYear()

System.out.println(new Date().getYear()); 
System.out.println(new GregorianCalendar().getTime().getYear()); 
System.out.println(this.sale.getSaleDate().getYear()); 
System.out.println(this.sale.getSaleDate().getMonth()); 
System.out.println(this.sale.getSaleDate().getDate()); 

vuelve

I/System.out(4274): 112 
I/System.out(4274): 112 
I/System.out(4274): 112 
I/System.out(4274): 1 
I/System.out(4274): 11 

No entiendo el 112 bit que pensé que habría sido 2012. ¿Qué está pasando? ¿La clase java.util.Date no se puede usar? Estoy almacenando esto como un campo en varios de mis clases para almacenar una fecha y hora. ¿Que debería hacer?

Respuesta

39

Según javadocs:

@Deprecated 
public int getYear() 

DEPRECATED. A partir de JDK versión 1.1, 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, tal como se interpreta en la zona horaria local.

Devuelve: el año representado por esta fecha, menos 1900.

Ver también: Calendar

Así que 112 es la salida correcta. Seguiría el consejo en el Javadoc o usaría JodaTime en su lugar.

+4

1 de JodaTime – dnault

+4

la correcta aplicación de una especificación totalmente Bizaare! –

+0

¿Es este el error Y2K? – jumpnett

9

Sí, esto es, de hecho, lo que está sucediendo. Véase también el Javadoc:

Returns: 
    the year represented by this date, minus 1900. 

El método getYear está en desuso por esta razón. Entonces, no lo uses.

Tenga en cuenta también que getMonth devuelve un número entre 0 y 11. Por lo tanto, this.sale.getSaleDate().getMonth() devuelve 1 para febrero, en lugar de 2. Mientras que java.util.Calendar no agrega 1900 a todos los años, sí lo hace de a poco. problema del mes

Está mucho mejor usando JodaTime.

1

Este comportamiento se documenta en la documentación java.util.Date -class:

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

También está marcado como obsoleto. Use java.util.Calendar en su lugar.

19

No utilice Date, utilice Calendar:

// Beware: months are zero-based and no out of range errors are reported 
Calendar date = new GregorianCalendar(2012, 9, 5); 
int year = date.get(Calendar.YEAR); // 2012 
int month = date.get(Calendar.MONTH); // 9 - October!!! 
int day = date.get(Calendar.DAY_OF_MONTH); // 5 

Es compatible con el tiempo, así:

Calendar dateTime = new GregorianCalendar(2012, 3, 4, 15, 16, 17); 
int hour = dateTime.get(Calendar.HOUR_OF_DAY); // 15 
int minute = dateTime.get(Calendar.MINUTE); // 16 
int second = dateTime.get(Calendar.SECOND); // 17 
30

formato de fecha de uso

SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
Date date = format.parse(datetime); 
SimpleDateFormat df = new SimpleDateFormat("yyyy"); 
year = df.format(date); 
32

Además de todos los comentarios, Pensé que podría agregar un código sobre cómo usar java.util.Date, java.util.Calendar yj ava.util.GregorianCalendar según el javadoc.

//Initialize your Date however you like it. 
Date date = new Date(); 
Calendar calendar = new GregorianCalendar(); 
calendar.setTime(date); 
int year = calendar.get(Calendar.YEAR); 
//Add one to month {0 - 11} 
int month = calendar.get(Calendar.MONTH) + 1; 
int day = calendar.get(Calendar.DAY_OF_MONTH); 
0
 try{ 
int year = Integer.parseInt(new Date().toString().split("-")[0]); 
} 
catch(NumberFormatException e){ 
} 

Gran parte de la fecha está en desuso.

+0

Sugiero hacer algo en la excepción. (Por ejemplo, código, bastará con un comentario "haz algo aquí"). "Comer" una excepción es una mala práctica, hace que la depuración sea difícil. –

2

tl; dr

LocalDate.now()  // Capture the date-only value current in the JVM’s current default time zone. 
     .getYear() // Extract the year number from that date. 

java.time

Tanto las clases java.util.Date y java.util.Calendar son legado, ahora suplantado por el marco java.time incorporado en Java 8 y más tarde.

Una zona horaria es crucial para determinar una fecha. Para cualquier momento dado, la fecha varía alrededor del mundo por zona. Por ejemplo, unos minutos después de la medianoche en Paris France es un nuevo día mientras aún está "ayer" en Montréal Québec.

Si no se especifica la zona horaria, la JVM aplica implícitamente su zona horaria predeterminada actual. Ese valor predeterminado puede cambiar en cualquier momento, por lo que sus resultados pueden variar. Es mejor especificar su zona horaria deseada/esperada explícitamente como un argumento.

Especifique un proper time zone name en el formato de continent/region, como America/Montreal, Africa/Casablanca, o Pacific/Auckland. Nunca use la abreviatura de 3-4 letras como EST o IST ya que son no zonas horarias verdaderas, no estandarizadas, y ni siquiera únicas (!).

ZoneId z = ZoneId.of("Africa/Tunis") ; 

Si desea sólo la fecha sin la hora del día, utilizar LocalDate. Esta clase carece de información de zona horaria pero puede especificar una zona horaria para determinar la fecha actual.

ZoneId zoneId = ZoneId.of("America/Montreal"); 
LocalDate localDate = LocalDate.now(zoneId); 

Puede obtener las diferentes piezas de información con getYear, getMonth, y getDayOfMonth. ¡Obtendrás el número del año con java.time!

int year = localDate.getYear(); 

Si desea una fecha-hora en lugar de sólo una fecha, utilizar ZonedDateTime clase.

ZonedDateTime zdt = ZonedDateTime.now(zoneId) ; 

Sobre java.time

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

El proyecto Joda-Time, ahora en maintenance mode, recomienda la migración a las clases java.time.

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

Gran parte de la funcionalidad java.time se back-portado a Java 6 & Java 7 en ThreeTen-Backport y adaptado además para Android en ThreeTenABP (ver How to use…).

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 more.

clase
5

Java 8 LocalDate es otra opción para obtener el año de una java.util.Date,

int year = LocalDate.parse(new SimpleDateFormat("yyyy-MM-dd").format(date)).getYear(); 

Otra opción es,

int year = Integer.parseInt(new SimpleDateFormat("yyyy").format(date)); 
+0

¿Por qué mezclaría la problemática clase heredada 'SimpleDateFormat' con las modernas clases * java.time *? Utilice [ 'DateTimeFormatter'] (https://docs.oracle.com/javase/9/docs/api/java/time/format/DateTimeFormatter.html), la clase que reemplaza totalmente' SimpleDateFormat'. –

0

La documentación de Java sugiere hacer uso de Calendario clase en lugar de esta forma obsoleta Aquí está el código de muestra para configurar el objeto de calendario

Calendar calendar = Calendar.getInstance(); 
calendar.setTime(new Date()); 

Aquí está el código de ejemplo para obtener el año, mes, etc.

System.out.println(calendar.get(Calendar.YEAR)); 
System.out.println(calendar.get(Calendar.MONTH)); 

Calendario también tiene soporte para muchas otras informaciones útiles como, TIEMPO, DAY_OF_MONTH, etc. Aquí la lista documentation todos ellos Atención: que el mes está basado en 0 Enero es el 0 ° mes.

+1

clases FYI, el problemático pasado de fecha y hora como [ 'java.util.Date'] (https://docs.oracle.com/javase/9/docs/api/java/util/Date.html), [ 'java.util.Calendar'] (https://docs.oracle.com/javase/9/docs/api/java/util/Calendar.html), y' java.text.SimpleDateFormat' son ahora [legacy] (https://en.wikipedia.org/wiki/Legacy_system), suplantado por el [java.time] (https://docs.oracle.com/javase/9/docs/api/java/time/package-summary. html) clases integradas en Java 8 y Java 9. Consulte [* Tutorial * de Oracle] (https://docs.oracle.com/javase/tutorial/datetime/TOC.html). –

1

Year.now()

Hay una manera más fácil de utilizar la biblioteca java.time en Java 8+. La expresión:

java.time.Year.now().getValue() 

devuelve el año actual como un int de cuatro dígitos, utilizando su zona horaria predeterminada. Hay muchas opciones para diferentes tiempos ZoneId s, Calendar sy Clock s, pero creo que esto es lo que querrá la mayoría del tiempo. Si desea que el código se vea más limpio (y no necesita ningún otro java.time. *.Ahora() funciones), ponga:

import static java.time.Year.now; 

en la parte superior de su archivo, y llamar a:

now().getValue() 

según sea necesario.

Cuestiones relacionadas