====== Fecha y hora ====== En este tema veremos la nueva API para gestión de fechas que se introdujo en Java 8. Comprenden clases y métodos para almacenar valores de fechas y poder trabajar con ellos. Les echaremos un vistazo a los tipos y operaciones más comunes para trabajar con fechas y períodos de tiempo. ===== Tipos para almacenar fechas ===== ==== LocalDate ==== La clase ''LocalDate'' permite almacenar el valor de una fecha sin hora de la que podremos extraer los partes de fecha que podamos necesitar mediante métodos //getter//. // La fecha de hoy LocalDate fechaHoy = LocalDate.now(); // Una fecha concreta LocalDate fecha = LocalDate.of(2018, Month.NOVEMBER, 26); System.out.println(fecha); // 2018-11-26 DayOfWeek dia = fecha.getDayOfWeek(); Month mes = fecha.getMonth(); int diaDelMes = fecha.getDayOfMonth(); int numeroMes = fecha.getMonthValue(); int numeroAno = fecha.getYear(); ==== LocalTime ==== La clase ''LocalTime'' permite almacenar horas (hora, minuto y segundo). El funcionamiento es similar a la clase ''LocalDate'': LocalTime ahora = LocalTime.now(); int hora = ahora.getHour(); int minutos = ahora.getMinute(); int segundos = ahora.getSecond(); ==== DayOfWeek ==== Esta enumeración permite almacenar valores que representan el día de la semana // Podemos almacenar un día de la semana DayOfWeek diaSemana = DayOfWeek.MONDAY; // El día siguiente diaSemana = diaSemana.plus(1); // Hace dos días diaSemana = diaSemana.minus(2); También podemos obtener su representación por pantalla en función de la configuración de idioma de nuestra aplicación: DayOfWeek diaSemana = DayOfWeek.FRIDAY; Locale locale = new Locale("es", "ES"); System.out.println(diaSemana.getDisplayName(TextStyle.FULL, locale)); // viernes System.out.println(diaSemana.getDisplayName(TextStyle.NARROW, locale)); // V System.out.println(diaSemana.getDisplayName(TextStyle.SHORT, locale)); // vie ==== Month ==== Esta enumeración permite almacenar valores que representan un mes // Podemos almacenar un mes Month mes = Month.NOVEMBER; // Dentro de dos meses mes = Month.NOVEMBER; mes = mes.plus(3); System.out.println(mes); // FEBRUARY // Hace dos meses mes = mes.minus(2); System.out.println(mes); // DECEMBER También podemos obtener su representación por pantalla en función de la configuración de idioma de nuestra aplicación: Month mes = Month.NOVEMBER; Locale locale = new Locale("es", "ES"); System.out.println(mes.getDisplayName(TextStyle.FULL, locale)); // noviembre System.out.println(mes.getDisplayName(TextStyle.NARROW, locale)); // N System.out.println(mes.getDisplayName(TextStyle.SHORT, locale)); // nov ===== Operaciones con fechas ===== Como hemos dicho, además de proporcionar los tipos de datos y estructuras para almacenar valores de fecha y sus partes, la nueva API de fechas de Java también proporciona métodos para realizar operaciones con estos datos. LocalDate fechaHoy = LocalDate.now(); System.out.println("Este año es bisiesto?: " + fechaHoy.isLeapYear()); // false System.out.println(fechaHoy.minus(Period.ofWeeks(3))); // 2018-11-03 System.out.println(fechaHoy.plus(Period.ofDays(35))); // 2018-12-29 === Formatear una fecha === También se puede formatear el valor de la fecha para que pueda ser representado como una cadena de texto y viceversa: // Pasa la fecha a una representación en String String cadenaFecha = fechaHoy.format(DateTimeFormatter.ofPattern("dd/MM/yyyy")); === Parsear una fecha === // Pasa la representación en String a un valor de fecha LocalDate.parse(cadenaFecha, DateTimeFormatter.ofPattern("dd/MM/yyyy")); Se pueden ver más ejemplos de formatos de fecha y patrones en la API de Java correspondiente a la [[https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html|clase DateTimeFormatter]] === Comparar dos fechas === También es posible comparar dos fechas entre ellas directamente para saber cuál es anterior/posterior o si son iguales LocalDate fechaHoy = LocalDate.now(); LocalDate fechaAyer = LocalDate.now().minus(Period.ofDays(1)); System.out.println(fechaHoy.isAfter(fechaAyer)); // true System.out.println(fechaHoy.isBefore(fechaAyer)); // false System.out.println(fechaHoy.equals(fechaAyer)); // false De forma muy similar, podremos realizar estas mismas operaciones con horas utilizando el tipo de datos ''LocalTime'' que hemos visto más arriba. Y saber cuál es la distancia entre dos fechas determinadas: LocalDate fechaHoy = LocalDate.now(); LocalDate fechaAyer = LocalDate.now().minus(Period.ofDays(1)); // Una vez calculada la distancia entre las fechas Period periodo = fechaHoy.until(fechaAyer); // Puedo verla en dias, meses, . . . System.out.println(periodo.getDays()); // -1 ==== Conversiones de fechas (Date <-> LocalDate) ==== === De java.util.Date a LocalDate === fechaDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate() === De java.util.Date a LocalDateTime === Instant.ofEpochMilli(fechaDate.getTime()) .atZone(ZoneId.systemDefault()) .toLocalDateTime(); === De LocalDateTime a java.util.Date === java.util.Date.from(fechaLocalDateTime .atStartOfDay() .atZone(ZoneId.systemDefault()) .toInstant(); === De LocalDate a java.util.Date === java.util.Date.from(fechaLocalDate.atZone(ZoneId.systemDefault()) .toInstant(); === De LocalDate a java.sql.Date === java.sql.Date.valueOf(localDate); === De java.sql.Date a LocalDate === LocalDate localDate = new java.sql.Date(date.getTime()).toLocalDate(); === De java.sql.Date a java.util.Date === java.util.Date fechaUtilDate = new java.util.Date(fechaSqlDate.getTime()); === De java.util.Date a java.sql.Date === java.sql.Date fechaSqlDate = new java.sql.Date(fechaUtilDate.getTime()); ---- (c) 2019-{{date>%Y}} Santiago Faci