variable restar manejo horas fechas fecha ejemplo declarar java date calendar

manejo - restar fechas en java 8



Fecha de Java vs Calendario (13)

Alguien podría informar sobre las "mejores prácticas" actuales en relación con los tipos de Date y Calendar .

Al escribir un nuevo código, ¿es mejor favorecer siempre el Calendar Date o existen circunstancias en las que la Date es el tipo de datos más apropiado?


tl; dr

Asesorar a las "mejores prácticas" actuales sobre Date y Calendar

¿Es mejor favorecer siempre el Calendar sobre la Date

Evita estas clases heredadas por completo. Utilice java.time clases java.time lugar.

  • Por un momento en UTC , use Instant
    (el equivalente moderno de la Date )
  • Por un momento en una zona horaria particular, use ZonedDateTime
    (El equivalente moderno de GregorianCalendar )
  • Por un momento en un determinado offset-from-UTC , use OffsetDateTime
    (no equivalente en clases heredadas)
  • Para una fecha y hora (no un momento) con zona horaria o desplazamiento desconocidos, use LocalDateTime
    (no equivalente en clases heredadas)

Detalles

La Respuesta de Ortomala Lokni tiene razón al sugerir el uso de las clases modernas de java.time lugar de las antiguas y problemáticas clases de fecha y hora ( Date , Calendar , etc.). Pero esa Respuesta sugiere que la clase equivocada es equivalente (vea mi comentario sobre esa Respuesta).

Usando java.time

Las clases de java.time son una gran mejora con respecto a las clases de fecha y hora heredadas, la diferencia de la noche y el día. Las clases antiguas están mal diseñadas, son confusas y problemáticas. Debes evitar las clases antiguas siempre que sea posible. Pero cuando necesita convertir a / de lo antiguo / nuevo, puede hacerlo llamando a nuevos métodos para agregar a las clases antiguas .

Para obtener más información sobre la conversión, vea mi respuesta y el diagrama ingenioso a otra pregunta, ¿ Convertir java.util.Fecha a qué tipo de "java.time"? .

Searching ofrece cientos de ejemplos de preguntas y respuestas sobre el uso de java.time. Pero aquí hay una sinopsis rápida.

Instant

Obtén el momento actual con un Instant . La clase Instant representa un momento en la línea de tiempo en UTC con una resolución de nanoseconds (hasta nueve (9) dígitos de una fracción decimal).

Instant instant = Instant.now();

ZonedDateTime

Para ver ese mismo momento simultáneo a través de la lente de la hora del reloj de pared de alguna región en particular, aplique una zona horaria ( ZoneId ) para obtener un ZonedDateTime .

Zona horaria

Especifique un nombre de zona horaria adecuado en el formato de continent/region , como America/Montreal , Africa/Casablanca o Pacific/Auckland . Nunca use la abreviatura de 3 a 4 letras, como EST o IST ya que no son zonas horarias verdaderas, no están estandarizadas y ni siquiera son únicas (!).

ZoneId z = ZoneId.of( "America/Montreal" ); ZonedDateTime zdt = instant.atZone();

Compensar

Una zona horaria es el historial de cambios de una región en su offset-from-UTC . Pero a veces te dan solo un desplazamiento sin la zona completa. En ese caso, use la clase OffsetDateTime .

ZoneOffset offset = ZoneOffset.parse( "+05:30" ); OffsetDateTime odt = instant.atOffset( offset );

El uso de una zona horaria es preferible al uso de un simple desplazamiento.

LocalDateTime

Las clases "locales" en las clases Local… significan cualquier localidad, no una localidad en particular. Entonces el nombre puede ser contraintuitivo.

LocalDateTime , LocalDate y LocalTime carecen a propósito de cualquier información sobre el desplazamiento o la zona horaria. Entonces, no representan momentos reales, no son puntos en la línea de tiempo. En caso de duda o confusión, use ZonedDateTime lugar de LocalDateTime . Search para mucha más discusión.

Instrumentos de cuerda

No combine los objetos de fecha y hora con cadenas que representan su valor. Puede analizar una cadena para obtener un objeto de fecha y hora, y puede generar una cadena a partir de un objeto de fecha y hora. Pero la cadena nunca es la misma fecha.

Obtenga información sobre los formatos estándar ISO 8601 , que se utilizan de forma predeterminada en las clases java.time.

Acerca de java.time

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

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

Para obtener más información, consulte el Tutorial de Oracle . Y busca para muchos ejemplos y explicaciones. La especificación es JSR-310 .

Utilizando un controlador JDBC compatible con JDBC 4.2 o posterior, puede intercambiar objetos java.time directamente con su base de datos. No hay necesidad de cadenas ni clases java.sql. *.

¿Dónde obtener las clases java.time?

  • Java SE 8 , Java SE 9 y posteriores
    • Incorporado.
    • Parte de la API de Java estándar con una implementación en paquete.
    • Java 9 agrega algunas características menores y correcciones.
  • Java SE 6 y Java SE 7
    • Gran parte de la funcionalidad de java.time está respaldada a Java 6 y 7 en ThreeTen-Backport .
  • Android
    • Versiones posteriores de las implementaciones de paquetes de Android de las clases java.time.
    • Para Android anterior, el proyecto ThreeTenABP adapta ThreeTen-Backport (mencionado anteriormente). Vea Cómo usar ThreeTenABP… .

El proyecto ThreeTen-Extra extiende 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 .


Con Java 8, se debe usar el nuevo paquete java.time .

Los objetos son inmutables, las zonas horarias y el horario de verano se tienen en cuenta.

Puede crear un objeto ZonedDateTime partir de un objeto java.util.Date antiguo como este:

Date date = new Date(); ZonedDateTime zonedDateTime = date.toInstant().atZone(ZoneId.systemDefault());


Generalmente uso la fecha si es posible. Aunque es mutable, los mutadores están en desuso. Al final, básicamente se ajusta un largo que representaría la fecha / hora. A la inversa, usaría Calendarios si tuviera que manipular los valores.

Puede pensarlo de esta manera: solo usa StringBuffer solo cuando necesita tener cadenas que puede manipular fácilmente y luego convertirlas en cadenas utilizando el método toString (). De la misma manera, solo uso el Calendario si necesito manipular datos temporales.

Para las mejores prácticas, tiendo a usar objetos inmutables tanto como sea posible fuera del modelo de dominio . Reduce significativamente las posibilidades de efectos secundarios y lo realiza el compilador en lugar de una prueba de JUnit. Usas esta técnica creando campos finales privados en tu clase.

Y volviendo a la analogía de StringBuffer. Aquí hay un código que muestra cómo convertir entre el calendario y la fecha.

String s = "someString"; // immutable string StringBuffer buf = new StringBuffer(s); // mutable "string" via StringBuffer buf.append("x"); assertEquals("someStringx", buf.toString()); // convert to immutable String // immutable date with hard coded format. If you are hard // coding the format, best practice is to hard code the locale // of the format string, otherwise people in some parts of Europe // are going to be mad at you. Date date = new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH).parse("2001-01-02"); // Convert Date to a Calendar Calendar cal = Calendar.getInstance(); cal.setTime(date); // mutate the value cal.add(Calendar.YEAR, 1); // convert back to Date Date newDate = cal.getTime(); // assertEquals(new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH).parse("2002-01-02"), newDate);


La fecha debe ser re-desarrollada. En lugar de ser un interger largo, debe contener el año, mes, fecha, hora, minuto, segundo, como campos separados. Puede ser incluso bueno almacenar el calendario y la zona horaria a la que está asociada esta fecha.

En nuestra conversación natural, si programamos una cita el 1 de noviembre de 2013 a la 1 p.m. hora de Nueva York, este es un DateTime. NO es un calendario. Así que deberíamos poder conversar así también en Java.

Cuando la Fecha se almacena como un entero largo (de mili segundos desde el 1 de enero de 1970 o algo así), el cálculo de su fecha actual depende del calendario. Diferentes calendarios darán diferente fecha. Esto se debe a la posibilidad de dar un tiempo absoluto (por ejemplo, 1 billón de segundos después del Big Bang). Pero a menudo también necesitamos una forma cómoda de conversación, como un objeto que encapsula año, mes, etc.

Me pregunto si hay nuevos avances en Java para conciliar estos 2 objetivos. Tal vez mi conocimiento de Java es demasiado viejo.


La fecha es la mejor para almacenar un objeto de fecha. Es el persistido, el Serializado ...

El calendario es mejor para manipular fechas.

Nota: a veces también favorecemos java.lang.Long sobre Date, porque Date es mutable y por lo tanto no es seguro para subprocesos. En un objeto Date, use setTime () y getTime () para cambiar entre los dos. Por ejemplo, una fecha constante en la aplicación (ejemplos: el cero 1970/01/01, o un aplicativo END_OF_TIME que estableció a 2099/12/31; son muy útiles para reemplazar valores nulos como hora de inicio y hora de finalización, especialmente cuando los persistes en la base de datos, ya que SQL es tan peculiar con nulos).


La fecha es una clase más simple y está principalmente allí por razones de compatibilidad con versiones anteriores. Si necesita establecer fechas particulares o hacer aritmética de fechas, use un Calendario. Los calendarios también manejan la localización. Las funciones de manipulación de fechas anteriores de Date ya han quedado en desuso.

Personalmente, tiendo a usar el tiempo en milisegundos como largo (o largo, según corresponda) o calendario cuando hay una opción.

Tanto la fecha como el calendario son mutables, lo que tiende a presentar problemas al usar cualquiera de los dos en una API.


La mejor manera de obtener un nuevo código (si su política permite el código de terceros) es usar la joda-time.sourceforge.net .

Ambos, Date y Calendar , tienen tantos problemas de diseño que tampoco son buenas soluciones para el nuevo código.



Siempre abogo joda-time.sourceforge.net . Este es el por qué.

  1. La API es consistente e intuitiva. A diferencia de las API java.util.Date/Calendar
  2. no tiene problemas con los subprocesos, a diferencia de java.text.SimpleDateFormat etc. (He visto numerosos problemas de clientes relacionados con no saber que el formato de fecha / hora estándar no es seguro para subprocesos)
  3. Es la base de las nuevas API de fecha y hora de Java ( JSR310 , programadas para Java 8. Por lo tanto, utilizará API que se convertirán en API de Java centrales.

EDITAR: las clases de fecha / hora de Java introducidas con Java 8 ahora son la solución preferida, si puede migrar a Java 8


Un poco tarde en la fiesta, pero Java tiene una nueva API de fecha y hora en JDK 8. Es posible que desee actualizar su versión de JDK y adoptar el estándar. No más fecha / calendario desordenados, no más frascos de terceros.


Utilizo el Calendario cuando necesito algunas operaciones específicas en las fechas, como la mudanza en el tiempo, pero la Fecha me resulta útil cuando se necesita formatear la fecha para adaptar sus necesidades, recientemente descubrí que Locale tiene muchas operaciones y métodos útiles. Estoy usando Locale ahora mismo!


Date s debe utilizarse como puntos inmutables en el tiempo; Calendar son mutables, y se pueden pasar y modificar si necesita colaborar con otras clases para llegar a una fecha final. Considérelos análogos a String y StringBuilder y entenderá cómo considero que deberían usarse.

(Y sí, sé que la fecha no es técnicamente inmutable, pero la intención es que no sea mutable, y si nada llama a los métodos desaprobados, entonces es así).


  • Date y el Calendar son realmente el mismo concepto fundamental (ambos representan un instante en el tiempo y se envuelven alrededor de un valor long subyacente).

  • Se podría argumentar que el Calendar realidad es aún más roto que el de Date , ya que parece ofrecer datos concretos sobre cosas como el día de la semana y la hora del día, mientras que si cambia su propiedad de zona timeZone , ¡el concreto se convierte en un cambio de timeZone ! Ninguno de los objetos es realmente útil como almacén de año-mes-día o hora del día por esta razón.

  • Use el Calendar solo como una calculadora que, cuando se le den los objetos Date y TimeZone , hará los cálculos por usted. Evite su uso para escribir propiedades en una aplicación.

  • Use SimpleDateFormat junto con TimeZone y Date para generar cadenas de visualización.

  • Si te sientes aventurero, usa Joda-Time, aunque IMHO es innecesariamente complicado y pronto será superado por la API de fecha JSR-310 en cualquier caso.

  • He respondido anteriormente que no es difícil rodar tu propia clase de YearMonthDay , que usa el Calendar bajo el capó para los cálculos de fechas. Me votaron por la sugerencia, pero sigo creyendo que es válida porque Joda-Time (y JSR-310 ) son realmente demasiado complicados para la mayoría de los casos de uso.