svish
Vengo del mundo de C#, por lo que aún no tengo mucha experiencia con Java. Eclipse me acaba de decir que Date
estaba en desuso:
Person p = new Person();
p.setDateOfBirth(new Date(1985, 1, 1));
¿Por qué? ¿Y qué (especialmente en casos como el anterior) debería usarse en su lugar?
BúfaloBúfalo
El java.util.Date
La clase en realidad no está en desuso, solo ese constructor, junto con un par de otros constructores/métodos están en desuso. Estaba en desuso porque ese tipo de uso no funciona bien con la internacionalización. El Calendar
En su lugar, se debe usar la clase:
Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, 1988);
cal.set(Calendar.MONTH, Calendar.JANUARY);
cal.set(Calendar.DAY_OF_MONTH, 1);
Date dateRepresentation = cal.getTime();
Eche un vistazo a la fecha Javadoc:
http://download.oracle.com/javase/6/docs/api/java/util/Date.html
-
Esta debería ser la mejor respuesta. Gracias.
– jordaniac89
28 de mayo de 2015 a las 2:02
-
Al decir “no funciona bien con la internacionalización”, ¿quiere decir que para la fecha, no puede asignarle una zona horaria? Gracias
– Sumergirse en
1 de diciembre de 2015 a las 5:55
-
¿Qué hizo Date fue analizar una cadena, por lo que ahora tenemos que subcadenar una cadena que contiene el año, el mes y el día? Parece una gran cantidad de problemas adicionales para algo que, en la mayoría de los casos, no necesita una lógica y métodos tan complejos que se le agreguen.
– G_V
6 de marzo de 2017 a las 8:39
-
Solo para agregar, esto tendrá en cuenta la zona horaria predeterminada. Si queremos especificar cualquier otra zona horaria, podemos usar
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone(<timezone id>));
– Vikas Prasad
17/03/2017 a las 16:45
-
“La clase Calendario debería usarse en su lugar” – Para Java 8 y posteriores, el
java.time.*
las clases son la mejor opción… si está cambiando su código.– Esteban C.
30 de mayo de 2018 a las 6:15
albahaca bourque
tl; dr
LocalDate.of( 1985 , 1 , 1 )
…o…
LocalDate.of( 1985 , Month.JANUARY , 1 )
Detalles
El java.util.Date
, java.util.Calendar
y java.text.SimpleDateFormat
las clases se apresuraron demasiado cuando Java se lanzó y evolucionó por primera vez. Las clases no estaban bien diseñadas o implementadas. Se intentaron mejoras, por lo tanto, las obsolescencias que ha encontrado. Lamentablemente, los intentos de mejora fracasaron en gran medida. Debería evitar estas clases en total. Son suplantados en Java 8 por nuevas clases.
Problemas en su código
Un java.util.Date tiene una porción de fecha y hora. Ignoraste la porción de tiempo en tu código. Entonces, la clase Fecha tomará el comienzo del día según lo define la zona horaria predeterminada de su JVM y aplicará esa hora al objeto Fecha. Por lo tanto, los resultados de su código variarán según la máquina que se ejecute o la zona horaria configurada. Probablemente no sea lo que quieres.
Si solo desea la fecha, sin la parte de la hora, como para una fecha de nacimiento, es posible que no desee utilizar un Date
objeto. Es posible que desee almacenar solo una cadena de la fecha, en ISO 8601 formato de YYYY-MM-DD
. O usa un LocalDate
objeto de Joda-Time (ver más abajo).
Joda-Tiempo
Lo primero que debe aprender en Java: Evite las clases java.util.Date y java.util.Calendar notoriamente problemáticas incluido con Java.
Como se señaló correctamente en la respuesta del usuario 3277382, use cualquiera Joda-Tiempo o el nuevo paquete java.time.* en Java 8.
Código de ejemplo en Joda-Time 2.3
DateTimeZone timeZoneNorway = DateTimeZone.forID( "Europe/Oslo" );
DateTime birthDateTime_InNorway = new DateTime( 1985, 1, 1, 3, 2, 1, timeZoneNorway );
DateTimeZone timeZoneNewYork = DateTimeZone.forID( "America/New_York" );
DateTime birthDateTime_InNewYork = birthDateTime_InNorway.toDateTime( timeZoneNewYork );
DateTime birthDateTime_UtcGmt = birthDateTime_InNorway.toDateTime( DateTimeZone.UTC );
LocalDate birthDate = new LocalDate( 1985, 1, 1 );
Volcar a la consola…
System.out.println( "birthDateTime_InNorway: " + birthDateTime_InNorway );
System.out.println( "birthDateTime_InNewYork: " + birthDateTime_InNewYork );
System.out.println( "birthDateTime_UtcGmt: " + birthDateTime_UtcGmt );
System.out.println( "birthDate: " + birthDate );
Cuando se ejecuta…
birthDateTime_InNorway: 1985-01-01T03:02:01.000+01:00
birthDateTime_InNewYork: 1984-12-31T21:02:01.000-05:00
birthDateTime_UtcGmt: 1985-01-01T02:02:01.000Z
birthDate: 1985-01-01
java.tiempo
En este caso el código de java.tiempo es casi idéntico al de Joda-Tiempo.
Obtenemos una zona horaria (ZoneId
), y construya un objeto de fecha y hora asignado a esa zona horaria (ZonedDateTime
). Luego usando el Objetos inmutables patrón, creamos nuevas fechas y horas basadas en el mismo instante del objeto anterior (recuento de nanosegundos desde época) pero se le asignó otra zona horaria. Por último obtenemos un LocalDate
que no tiene hora del día ni zona horaria, aunque tenga en cuenta que la zona horaria se aplica al determinar esa fecha (un nuevo día amanece antes en Oslo que en Nueva York Por ejemplo).
ZoneId zoneId_Norway = ZoneId.of( "Europe/Oslo" );
ZonedDateTime zdt_Norway = ZonedDateTime.of( 1985 , 1 , 1 , 3 , 2 , 1 , 0 , zoneId_Norway );
ZoneId zoneId_NewYork = ZonedId.of( "America/New_York" );
ZonedDateTime zdt_NewYork = zdt_Norway.withZoneSameInstant( zoneId_NewYork );
ZonedDateTime zdt_Utc = zdt_Norway.withZoneSameInstant( ZoneOffset.UTC ); // Or, next line is similar.
Instant instant = zdt_Norway.toInstant(); // Instant is always in UTC.
LocalDate localDate_Norway = zdt_Norway.toLocalDate();
Acerca de java.tiempo
El java.tiempo framework está integrado en Java 8 y versiones posteriores. Estas clases suplantan a las viejas y problemáticas legado clases de fecha y hora como java.util.Date
, Calendar
& SimpleDateFormat
.
Para obtener más información, consulte la Tutorial de oráculo. Y busque Stack Overflow para obtener muchos ejemplos y explicaciones. La especificación es JSR 310.
El Joda-Tiempo proyecto, ahora en modo de mantenimientoaconseja la migración a la java.tiempo clases
puedes intercambiar java.tiempo objetos directamente con su base de datos. Usar una controlador JDBC conforme con JDBC 4.2 o después. No hay necesidad de cuerdas, no hay necesidad de java.sql.*
clases Compatibilidad con Hibernate 5 y JPA 2.2 java.tiempo.
¿Dónde obtener las clases java.time?
- Java SE 8, Java SE 9, Java SE 10, Java SE 11y posteriores: parte de la API de Java estándar con una implementación integrada.
- Java 9 trajo algunas características y correcciones menores.
- Java SE 6 y Java SE 7
- La mayoría de java.tiempo la funcionalidad está adaptada a Java 6 y 7 en ThreeTen-Backport.
- Androide
- Las versiones posteriores de Android (26+) incluyen implementaciones del java.tiempo clases
- Para versiones anteriores de Android (API desazucarado para proporcionar un subconjunto de los java.tiempo funcionalidad no integrada originalmente en Android.
- Si el desazucarado no te ofrece lo que necesitas, el TresDiezABP el proyecto se adapta ThreeTen-Backport (mencionado anteriormente) a Android. Ver Cómo usar ThreeTenABP….
-
Apoyos para mencionar realmente la causa raíz y brindar cobertura de todas las alternativas disponibles.
– mabi
11 de abril de 2016 a las 13:52
-
Esta es la respuesta correcta y debe evitarse la clase Calendario. ThreeTen es la mejor opción
– hormiga2009
16 de noviembre de 2019 a las 14:21
-
@Basil Bourque Usted menciona versiones posteriores de implementaciones de paquetes de Android de clases java.time. ¿Puedes ser más específico sobre qué versiones? Estoy tratando de reemplazar el código antiguo de fecha y calendario para una aplicación de Android y no estoy seguro de por dónde empezar.
– AJW
22 de noviembre de 2021 a las 3:37
-
@AJW Esa información ya está presentada en la última sección de la Respuesta, “Acerca de java.time”, que actualicé hace un momento.
– Basil Bourque
22 de noviembre de 2021 a las 6:10
-
Muy bien, gracias por la actualización.
– AJW
22 de noviembre de 2021 a las 15:17
Rubén
Lo especifico Date
constructor está en desuso, y Calendar
debe usarse en su lugar. El JavaDoc
para Fecha describe qué constructores están en desuso y cómo reemplazarlos usando un Calendar
.
-
El calendario requiere un objeto adicional y como 8 líneas más de código para hacer lo mismo, que es crear un objeto Fecha por lo que puedo decir. Es confuso y parece innecesario cuando solo necesita una fecha y no una variable ajustada de zona horaria.
– G_V
6 de marzo de 2017 a las 8:37
-
FYI, las viejas clases de fecha y hora terriblemente problemáticas como
java.util.Date
,java.util.Calendar
yjava.text.SimpleDateFormat
son ahora legadosuplantado por el java.tiempo Clases integradas en Java 8 y versiones posteriores. Ver Tutorial por Oracle.– Basil Bourque
28 de noviembre de 2018 a las 19:18
Kevin trabajador
Encontré esta pregunta como un duplicado de una pregunta más nueva que preguntaba cuál era la forma no obsoleta de obtener un Date
en un año, mes y día específicos.
Las respuestas aquí hasta ahora dicen usar el Calendar
clase, y eso fue cierto hasta que salió Java 8. Pero a partir de Java 8, la forma estándar de hacer esto es:
LocalDate localDate = LocalDate.of(1985, 1, 1);
Y luego, si realmente necesitas un java.util.Date
puede utilizar las sugerencias de esta pregunta.
Para obtener más información, consulte la API o los tutoriales para Java 8.
esteban c
Una de las razones por las que el constructor está en desuso es que el significado del parámetro del año no es el esperado. El javadoc dice:
A partir de la versión 1.1 de JDK, reemplazada por
Calendar.set(year + 1900, month, date)
.
Observe que el campo del año es el número de años desde 1900
, por lo que su código de muestra probablemente no hará lo que espera que haga. Y ese es el punto.
En general, el Date
La API solo es compatible con el calendario occidental moderno, tiene componentes especificados idiosincráticamente y se comporta de manera inconsistente si establece campos.
El Calendar
y GregorianCalendar
Las API son mejores que Date
, y las API de Joda-time de terceros generalmente se consideraban las mejores. En Java 8, introdujeron el java.time
paquetes, y estos son ahora la alternativa recomendada.
-
Esta solución funciona muy bien, excepto que no usa tiempo cero para horas-minutos-segundos-milisegundos como lo hizo la nueva fecha (año, mes, día). Entonces necesitamos algo como: Calendar cal = Calendar.getInstance(); cal.clear(); cal.set(año + 1900, mes, fecha); Fecha representación de fecha = cal.getTime();
– Joel Richard Koett
3 mayo 2019 a las 23:02
nbrooks
Tenga en cuenta que Calendar.getTime()
es no determinista en el sentido de que el hora del día parte por defecto a la hora actual.
Para reproducir, intente ejecutar el siguiente código un par de veces:
Calendar c = Calendar.getInstance();
c.set(2010, 2, 7); // NB: 2 means March, not February!
System.err.println(c.getTime());
Salida, por ejemplo:
Sun Mar 07 10:46:21 CET 2010
Ejecutar exactamente el mismo código un par de minutos más tarde produce:
Sun Mar 07 10:57:51 CET 2010
Entonces, mientras set()
obliga a los campos correspondientes a corregir los valores, filtra el tiempo del sistema para los otros campos. (Probado anteriormente con Sun jdk6 y jdk7)
-
Esta solución funciona muy bien, excepto que no usa tiempo cero para horas-minutos-segundos-milisegundos como lo hizo la nueva fecha (año, mes, día). Entonces necesitamos algo como: Calendar cal = Calendar.getInstance(); cal.clear(); cal.set(año + 1900, mes, fecha); Fecha representación de fecha = cal.getTime();
– Joel Richard Koett
3 mayo 2019 a las 23:02
robar w
Date
en sí mismo no está en desuso. Es solo que muchos de sus métodos lo son. Ver aquí para más detalles.
Usar java.util.Calendar
en cambio.
Estoy experimentando una curva de aprendizaje similar, también pasando de C# a Java. La otra cosa que me molestó es que el mes del año es un sistema basado en 0 (0 a 11 donde enero = 0 y diciembre = 11) pero los días del mes están basados en 1 (1 a 31). ¡Cuidado con eso!
-Paul Sasik
15 de abril de 2011 a las 13:36
@Paul Sasik, sí, pero hay una constante Calendar. JANUARY, por ejemplo, y una para cada mes
– Diogo
15 de abril de 2011 a las 14:07
@PaulSasik jajaja. Sí, estúpido Java. Tuve que cambiar de C# a Java y Dios mío, el dolor y la miseria.
– cbmeeks
22 de marzo de 2013 a las 13:56
posible duplicado de ¿Por qué la mayoría de los métodos java.util.Date quedaron en desuso?
– Tomás
26 de noviembre de 2013 a las 8:00
Los comentarios sarcásticos “lol” sobre Java de la gente de C# hicieron a mí reírse porque .Net obtuvo su biblioteca de fecha y hora decente (Hora de Noda) desde un puerto de la excelente biblioteca Java Joda-Tiempo.
– Basil Bourque
6 de febrero de 2014 a las 8:48