in

Fecha y hora de Java SE 8

¿Por qué necesitamos una nueva biblioteca de fecha y hora?

Un problema de larga data de los desarrolladores de Java ha sido el soporte inadecuado para los casos de uso de fecha y hora de los desarrolladores normales.

Publicado originalmente en la edición de enero / febrero de 2014 de Revista Java. Suscríbete hoy.

Por ejemplo, las clases existentes (como java.util.Date y SimpleDateFormatter) no son seguros para subprocesos, lo que genera problemas potenciales de concurrencia para los usuarios, algo con lo que el desarrollador promedio esperaría lidiar al escribir código de manejo de fechas.

Algunas de las clases de fecha y hora también presentan un diseño de API bastante deficiente. Por ejemplo, años en java.util.Date comienzan en 1900, los meses comienzan en 1 y los días comienzan en 0, lo que no es muy intuitivo.

Estos problemas, y varios otros, han llevado a la popularidad de las bibliotecas de fecha y hora de terceros, como Joda-Time.

Con el fin de abordar estos problemas y proporcionar un mejor soporte en el núcleo de JDK, se ha diseñado una nueva API de fecha y hora, que está libre de estos problemas, para Java SE 8.

El proyecto ha sido liderado conjuntamente por el autor de Joda-Time (Stephen Colebourne) y Oracle, bajo JSR 310, y aparecerá en el nuevo paquete Java SE 8 java.time.

Ideas centrales

La nueva API está impulsada por tres ideas centrales:

  • Clases de valores inmutables. Una de las serias debilidades de los formateadores existentes en Java es que no son seguros para subprocesos. Esto impone a los desarrolladores la carga de usarlos de una manera segura para subprocesos y de pensar en los problemas de concurrencia en su desarrollo diario del código de manejo de fechas. La nueva API evita este problema al garantizar que todas sus clases principales sean inmutables y representen valores bien definidos.
  • Diseño impulsado por dominios. La nueva API modela su dominio de manera muy precisa con clases que representan diferentes casos de uso para Date y Time cercanamente. Esto difiere de las bibliotecas Java anteriores que eran bastante deficientes en ese sentido. Por ejemplo, java.util.Date representa un instante en la línea de tiempo, una envoltura alrededor del número de milisegundos desde la época de UNIX, pero si llama toString(), el resultado sugiere que tiene una zona horaria, lo que genera confusión entre los desarrolladores.

    Este énfasis en el diseño impulsado por dominios ofrece beneficios a largo plazo en torno a la claridad y la comprensibilidad, pero es posible que deba pensar en el modelo de dominio de su aplicación de fechas cuando realice la migración de API anteriores a Java SE 8.

  • Separación de cronologías. La nueva API permite a las personas trabajar con diferentes sistemas de calendario para satisfacer las necesidades de los usuarios en algunas áreas del mundo, como Japón o Tailandia, que no necesariamente siguen la norma ISO-8601. Lo hace sin imponer una carga adicional a la mayoría de los desarrolladores, que necesitan trabajar solo con la cronología estándar.

LocalDate y LocalTime

Las primeras clases que probablemente encontrará al usar la nueva API son LocalDate y LocalTime. Son locales en el sentido de que representan la fecha y la hora del contexto del observador, como un calendario en un escritorio o un reloj en la pared. También hay una clase compuesta llamada LocalDateTime, que es un emparejamiento de LocalDate y LocalTime.

Las zonas horarias, que desambiguan los contextos de diferentes observadores, se dejan a un lado aquí; debe usar estas clases locales cuando no necesite ese contexto. Una aplicación JavaFX de escritorio podría ser una de esas ocasiones. Estas clases pueden incluso usarse para representar la hora en un sistema distribuido que tiene zonas horarias consistentes.

Las clases existentes no son seguras para subprocesos, lo que genera posibles problemas de concurrencia para los usuarios.no es algo que el desarrollador promedio esperaría.

Creando Objetos

Todas las clases principales de la nueva API se construyen mediante métodos de fábrica fluidos. Al construir un valor por sus campos constituyentes, la fábrica se llama of; al convertir de otro tipo, la fábrica se llama from. También hay métodos de análisis que toman cadenas como parámetros. Ver Listado 1.


LocalDateTime timePoint = LocalDateTime.now(
    );     // The current date and time
LocalDate.of(2012, Month.DECEMBER, 12); // from values
LocalDate.ofEpochDay(150);  // middle of 1970
LocalTime.of(17, 18); // the train I took home today
LocalTime.parse("10:15:30"); // From a String

Listado 1

Las convenciones estándar de obtención de Java se utilizan para obtener valores de las clases de Java SE 8, como se muestra en el Listado 2.


LocalDate theDate = timePoint.toLocalDate();
Month month = timePoint.getMonth();
int day = timePoint.getDayOfMonth();
timePoint.getSecond();

Listado 2

También puede modificar los valores del objeto para realizar cálculos. Debido a que todas las clases principales son inmutables en la nueva API, estos métodos se denominan with y devolver nuevos objetos, en lugar de usar setters (ver Listado 3). También existen métodos de cálculo basados ​​en los diferentes campos.


// Set the value, returning a new object
LocalDateTime thePast = timePoint.withDayOfMonth(
    10).withYear(2010);

/* You can use direct manipulation methods, 
    or pass a value and field pair */
LocalDateTime yetAnother = thePast.plusWeeks(
    3).plus(3, ChronoUnit.WEEKS);

Listado 3

La nueva API también tiene el concepto de ajustador: Un bloque de código que se puede utilizar para resumir la lógica de procesamiento común. Puede escribir un WithAdjuster, que se utiliza para establecer uno o más campos, o un PlusAdjuster, que se utiliza para sumar o restar algunos campos. Las clases de valor también pueden actuar como ajustadores, en cuyo caso actualizan los valores de los campos que representan. Los ajustadores integrados están definidos por la nueva API, pero puede escribir sus propios ajustadores si tiene una lógica empresarial específica que desea reutilizar. Ver Listado 4.


import static java.time.temporal.TemporalAdjusters.*;

LocalDateTime timePoint = ...
foo = timePoint.with(lastDayOfMonth());
bar = timePoint.with(previousOrSame(ChronoUnit.WEDNESDAY));

// Using value classes as adjusters
timePoint.with(LocalTime.now()); 

Listado 4

Truncamiento

La nueva API admite diferentes puntos de tiempo de precisión al ofrecer tipos para representar una fecha, una hora y una fecha con la hora, pero obviamente hay nociones de precisión que son más detalladas que esta.

los truncatedTo El método existe para admitir tales casos de uso y le permite truncar un valor en un campo, como se muestra en el Listado 5.

LocalTime truncatedTime = time.truncatedTo(ChronoUnit.SECONDS);

Listado 5

Zonas horarias

Las clases locales que analizamos anteriormente abstraen la complejidad introducida por las zonas horarias. Una zona horaria es un conjunto de reglas que corresponden a una región en la que la hora estándar es la misma. Hay alrededor de 40 de ellos. Las zonas horarias se definen por su diferencia con la hora universal coordinada (UTC). Se mueven aproximadamente en sincronía, pero con una diferencia específica.

Se puede hacer referencia a las zonas horarias mediante dos identificadores: abreviado, por ejemplo, «PLT», y más largo, por ejemplo, «Asia / Karachi». Al diseñar su aplicación, debe considerar qué escenarios son apropiados para usar zonas horarias y cuándo las compensaciones son apropiadas.

  • ZoneId es un identificador para una región (ver Listado 6). Cada ZoneId corresponde a algunas reglas que definen la zona horaria para esa ubicación. Al diseñar su software, si considera lanzar una cadena como «PLT» o «Asia / Karachi», debe usar esta clase de dominio en su lugar. Un caso de uso de ejemplo sería almacenar las preferencias de los usuarios para su zona horaria.

    
    // You can specify the zone id when creating a zoned date time
    ZoneId id = ZoneId.of("Europe/Paris");
    ZonedDateTime zoned = ZonedDateTime.of(dateTime, id);
    assertEquals(id, ZoneId.from(zoned));
    

    Listado 6

  • ZoneOffset es el período de tiempo que representa una diferencia entre Greenwich / UTC y una zona horaria. Esto se puede resolver para un ZoneId en un momento específico en el tiempo, como se muestra en el Listado 7.

    ZoneOffset offset = ZoneOffset.of("+2:00");

    Listado 7

Clases de zona horaria

  • ZonedDateTime es una fecha y hora con una zona horaria totalmente calificada (consulte el Listado 8). Esto puede resolver un desplazamiento en cualquier momento. La regla general es que si desea representar una fecha y hora sin depender del contexto de un servidor específico, debe usar ZonedDateTime.

    ZonedDateTime.parse("2007-12-03T10:15:30+01:00[Europe/Paris]");

    Listado 8

  • OffsetDateTime es una fecha y hora con un desplazamiento resuelto. Esto es útil para serializar datos en una base de datos y también debe usarse como formato de serialización para registrar marcas de tiempo si tiene servidores en diferentes zonas horarias.

  • OffsetTime es un tiempo con un desplazamiento resuelto, como se muestra en el Listado 9.

    
    OffsetTime time = OffsetTime.now();
    // changes offset, while keeping the same point on the timeline
    OffsetTime sameTimeDifferentOffset = time.withOffsetSameInstant(
        offset);
    // changes the offset, and updates the point on the timeline
    OffsetTime changeTimeWithNewOffset = time.withOffsetSameLocal(
        offset);
    // Can also create new object with altered fields as before
    changeTimeWithNewOffset
     .withHour(3)
     .plusSeconds(2);
    

    Listado 9

Existe una clase de zona horaria en Java:java.util.TimeZone—Pero Java SE 8 no lo usa porque todas las clases JSR 310 son inmutables y la zona horaria es mutable.

Periodos

A Period representa un valor como «3 meses y 1 día», que es una distancia en la línea de tiempo. Esto contrasta con las otras clases que hemos visto hasta ahora, que han sido puntos en la línea de tiempo. Consulte el Listado 10.


// 3 years, 2 months, 1 day
Period period = Period.of(3, 2, 1);

// You can modify the values of dates using periods
LocalDate newDate = oldDate.plus(period);
ZonedDateTime newDateTime = oldDateTime.minus(period);
// Components of a Period are represented by ChronoUnit values
assertEquals(1, period.get(ChronoUnit.DAYS)); 

Listado 10

Duraciones

A Duration es una distancia en la línea de tiempo medida en términos de tiempo, y cumple un propósito similar a Period, pero con diferente precisión, como se muestra en el Listado 11.


// A duration of 3 seconds and 5 nanoseconds
Duration duration = Duration.ofSeconds(3, 5);
Duration oneDay = Duration.between(today, yesterday);

Java SE 8 se enviará con una nueva API de fecha y hora en java.time que ofrece una seguridad y funcionalidad muy mejoradas para los desarrolladores. La nueva API modela bien el dominio, con una buena selección de clases para modelar una amplia variedad de casos de uso de desarrolladores.

Listado 11

Es posible realizar operaciones normales de más, menos y «con» en un Duration instancia y también para modificar el valor de una fecha u hora utilizando el Duration.

Cronologías

Para satisfacer las necesidades de los desarrolladores que utilizan sistemas de calendario que no son ISO, Java SE 8 introduce el concepto de Chronology, que representa un sistema de calendario y actúa como una fábrica de puntos de tiempo dentro del sistema de calendario. También hay interfaces que corresponden a clases de puntos de tiempo centrales, pero están parametrizadas por


Chronology:
ChronoLocalDate
ChronoLocalDateTime
ChronoZonedDateTime

Estas clases están disponibles exclusivamente para desarrolladores que están trabajando en aplicaciones altamente internacionalizadas que necesitan tener en cuenta los sistemas de calendario locales, y no deberían ser utilizadas por desarrolladores sin estos requisitos. Algunos sistemas de calendario …

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

1qCkJU6tMzhljY3DhlUg 0A

Experimente las tablas autoML de Google de forma gratuita

Excepciones de Java (Try … Catch)