10 oct 2016

Manejo de fechas en Java

java.util.Date


Durante mucho tiempo la clase utilizada para manejar fechas fue java.util.Date, pero hoy día muchos de sus métodos se consideran obsoletos.

java.util.Calendar


Posteriormente se utilizó la clase java.util.Calendar y java.util.GregorianCalendar. Su principal diferencia con Date, es que Calendar es mutable, permite cambiar el valor de un objeto sin tener que generar un nuevo objeto.
Calendar es una clase abstracta por lo que sus objetos deben instanciarse a través de alguna de sus clases heredadas, por ejemplo con el método getInstance() que nos devolvería la fecha actual del sistema o bien con GregorianCalendar, que sí es instanciable. Ejemplos:

Calendar hoy= Calendar.getInstance();
Calendar hoy= new GregorianCalendar();

Calendar dispone de métodos “get” y “set” que permiten recuperar o almacenar valores de las fechas, los correspondientes al argumento pasado, pero también tiene métodos “add” y “roll” que permiten a partir de unos valores incrementar o decrementar las fechas, recalculando las fechas correctas si es necesario.

Ejemplo:


Si quisiéramos darle valores, por ejemplo de una fecha de nacimiento, sería:



La clase Calendar permite trabajar de dos modos, en un modo indulgente o permisivo (Lenient), que es el que está activo por defecto, y que nos permitiría almacenar fechas sin realizar validaciones, por ejemplo darle al atributo día el valor 34, o no tener en cuenta sin un año es bisiesto, y un modo más restrictivo, que produciría una excepción de tipo IllegalArgumentException, si los parámetros de la fecha no son correctos.
Para activar el modo restrictivo, o no indulgente, pondríamos:
nacim.setLenient(false);

El ejemplo anterior con una fecha no válida, daría el siguiente resultado:



Paquete java.time


A partir de la versión 8 de Java se recomienda el uso del paquete java.time. Este paquete contiene clases para tratar fechas, tiempos, instantes y duraciones. Por ejemplo LocalTime, permite almacenar horas sin fecha, como: 14:37:26;  LocalDate, sirve para almacenar fechas sin hora, como 2015-05-22; LocalDateTime, permite almacenar fechas con hora.

LocalDate

Los objetos se crean con el método estático of() de la clase LocalDate.
LocalDate fecha = LocalDate.of(2016, 3, 27);

Si lo que queremos es obtener la fecha actual del sistema, utilizaremos el método now():
LocalDate ahora = LocalDate.now();

Dispone de métodos get para obtener los componentes día, mes y año de una fecha:
int dia, mes, anno;
dia= fecha.getDayOfMonth();
mes= fecha.getMonthValue(); //devuelve valores 1..12
anno= fecha.getYear();

Otros métodos get:
DayOfWeek diaSemana= fecha.getDayOfWeek();
Month nombreMes= fecha.getMonth();

Tiene métodos para incrementar, plus(), o para hacer retroceder una fecha, minus(). Estos métodos admiten dos argumentos el primero es el número de unidades y el segundo que expresa el tipo de unidades, mediante el tipo enumerado ChronoUnit, que tiene valores como DAYS, WEEKS, MONTHS o YEARS. Ejemplos:
LocalDate fecha2= fecha1.plus(5, ChronoUnit.MONTHS); //Aumenta fecha1, 5 meses
LocalDate fecha2= fecha1.minus(3, ChronoUnit.DAYS); //Disminuye fecha1, 3 días

Otros métodos interesantes:
·         isLeapYear()      verifica si un año es bisiesto
·         until()                   permite calcular el tiempo entre dos fechas
·         parse()                 permite analizar una cadena para generar una fecha

Para establecer el formato de las fechas, se utiliza la clase DateTimeFormatter.