Subido por Pedro López

Manejo de Fechas en Java 8

Anuncio
CLASE DATE
representa como su nombre indica a una fecha.
: viene incluida en Java, pero debemos importarla para nuestro
código. Date se localiza en el paquete java.util.
:
import java.util.Date;
Date fecha = new Date();
Si no le damos ningún parámetro, cogerá la fecha de hoy:
System.out.println(fecha);
CLASE DATE
También podemos crear una fecha propia, indicandoselo como
parámetro.
Date fecha2 = new Date(116, 5,3);
System.out.println(fecha2);
Esto es lo que veréis:
La explicación de los parámetros es la siguiente:
 116: Esto es el año, tenemos que tener en cuenta que inicialmente
empieza en 1900 y lo que hace es sumarle el valor que le demos
1900+116 = 2016. Si ponemos 2016 en realidad, sería el año 3916.
 5: este es el mes, pero si es el 5 ¿No debería ser Mayo? No, porque
empieza en 0 por lo que el 5 seria el sexto mes, en este caso Junio.
 3: este es el día, aquí es el día tal cual lo ponemos.
CLASE DATE
También podemos añadirle la hora exacta.
Date fecha2 = new Date(116, 5,3, 10, 5, 6);
System.out.println(fecha2);
Los 3 parámetros siguientes son la hora, minuto y segundo. Esto es lo
que devuelve.
También tenemos métodos para devolver cada uno de estos valores.
System.out.println("Año: "+ (fecha2.getYear()+1900) );
System.out.println("Mes: "+fecha2.getMonth());
System.out.println("Dia: "+fecha2.getDate());
System.out.println("Dia de la semana "+fecha2.getDay());
System.out.println("Hora: "+fecha2.getHours());
System.out.println("Minutos: "+fecha2.getMinutes());
System.out.println("Segundos: "+fecha2.getSeconds());
CLASE DATE
Esto es lo que nos devuelve:
Por último, mostraré dos funciones útiles de fechas, after y before.
System.out.println(fecha.after(fecha2));
System.out.println(fecha.before(fecha2));
Esto nos indica si una fecha (04/09/2016) esta después o antes que otra
fecha2 (03/06/2016). Esto nos devuelve:
En after, devuelve true porque 04/09/2016 esta después de 03/06/2016
y en before, devuelve false porque 04/09/2016 no esta
antes de 03/06/2016.
CLASE CALENDAR
Una subclase de Calendar representa una fecha de
acuerdo a las reglas de un calendario específico. Por ejemplo,
GregorianCalendar o varios tipos de calendarios lunares usados en
diferentes lugares del mundo.
: clase abstracta base para convertir entre un objeto de tipo Date
(java.util.Date) y un conjunto de campos enteros como YEAR (año),
MONTH (mes), DAY (día), HOUR (hora), etc. El verdadero sentido de
la clase Calendar no es obtener un instante de tiempo sino extraerle
datos.
: la clase java.util.Date tiene métodos que permiten
obtener el año, mes y día, pero estos métodos están obsoletos
precisamente por que para eso existe Calendar y de hecho cuando
usamos el método getYear() de la clase java.util.Date esta recurre a las
funcionalidades que posee la clase Calendar.
CLASE CALENDAR
El método getInstance() de la clase nos devuelve una subclase de
Calendar con el tiempo ajustado a la hora actual, y usamos el método
set(args…) para forzarlo a tomar la fecha deseada:
Calendar ahoraCal = Calendar.getInstance();
System.out.println(ahoraCal.getClass());
ahoraCal.set(2004,1,7);
System.out.println(ahoraCal.getTime());
ahoraCal.set(2004,1,7,7,0,0);
System.out.println(ahoraCal.getTime());
La primera línea devuelve una instancia de GregorianCalendar con la
fecha y hora actual y el método getTime() retorna un objeto de tipo
java.util.Date que se muestra en consola posteriormente.
La salida en consola será (tiene el formato de java.util.Date):
CLASE CALENDAR.
MODIFICAR ATRIBUTO
Modificar un atributo de Calendar es tan sencillo como obtenerlo,
solamente es necesario usar el método set(int atributo, int valor),
en donde atributo es una de las constantes mencionadas
anteriormente y valor es la cantidad que se le quiere asignar.
Por ejemplo: ahoraCal.set(Calendar.MONTH,Calendar.JANUARY) o
ahoraCal.set(Calendar.YEAR, 1980) ajustarían la fecha almacenada
en el objeto ahoraCal a enero o al año 1980 sin modificar ninguno de
los otros atributos.
CLASE CALENDAR.EJEMPLO
Mi cumpleaños es en octubre 27 :-), y deseo saber que día lo celebraré en el
2010; para eso obtengo una instancia de Calendar (que siempre devuelve un
objeto del tipo GregorianCalendar) y la ajusto hasta el 27 de octubre de
2010, luego obtengo el nombre del dia, veamos:
La salida es: 4, lo que quiere decir que en el 2010 el 27 de octubre será un
día miércoles.
GREGORIANCALENDAR Y
OPERACIONES
Realizar operaciones como sumar o restar días no es algo que dependa
directamente de Calendar sino más bien de una subclase de esta que
implemente algún tipo de calendario usado.
Es con esta clase con la que podemos sumar 2 ó 3 días a una fecha sin
preocuparnos por desbordamientos o recalcular meses o años.
Anteriormente vimos los métodos set() y get() de la clase Calendar para
obtener fechas y los datos de esas fechas, ahora veremos los métodos add() y
roll() que nos permiten avanzar un tiempo exacto sobre los datos obtenidos
anteriormente.
El método add(CONSTANTE, valor) suma algebraicamente valor a una
fecha; el valor a sumar asume el significado dado por CONSTANTE, que es
una de las definidas para la clase y que se mencionaron en la sección anterior
(MONTH, YEAR, SECOND, etc).
GREGORIANCALENDAR.
EJEMPLO
Por ejemplo agreguemos 3 días y 2 meses a la fecha actual:
Calendar hoy = Calendar.getInstance();
hoy.add(Calendar.DATE, 3);
hoy.add(Calendar.MONTH, 2);
System.out.println(hoy.getTime());
Ahora restemos 5 años y 50 días (Prúebalo en tu PC):
Calendar hoy = Calendar.getInstance();
hoy.add(Calendar.YEAR, -5);
hoy.add(Calendar.DATE, -50);
System.out.println(hoy.getTime());
Ahora prueba:
cal.add(Calendar.MINUTE, 70);
cal.add(Calendar.DATE, 22); //Así la fecha seía 1998/12/2 08:10:00
System.out.println(cal.getTime());
GREGORIANCALENDAR.
EJEMPLO 2
Método roll(CONSTANTE, valor)
Similar a add() salvo que no modifica ningún otro atributo, es decir,
cuando el atributo dado por CONSTANTE llega a su límite inferior o
superior cambia al límite contrario pero sin modificar sus atributos
siguientes. Este método se hizo para facilitar la funcionalidad en las
interfaces de usuario donde hay que especificar una fecha y tienen
botones para incrementar o decrementar alguno de los datos.
Si en el ejemplo anterior en vez de add() usamos roll() solo cambian los
valores que se especificaron directamente.
cal.roll(Calendar.MINUTE, 70);
cal.roll(Calendar.DATE, 22); //Así la fecha seía 1998/11/2 07:10:00
System.out.println(cal.getTime());
El uso de roll no es muy común excepto en ambientes gráficos, los
métodos que en verdad deben ser considerados, estudiados y probados
son set(), get() y add().
PAQUETE JAVA.TIME
extensión a las clases Date y Calendar del paquete
java.util, para manejo de fechas, horas y localización. Surge en Java 8.
: representan los principales conceptos de fecha - hora, incluyendo
instantes, fechas, horas, periodos, zonas de tiempo, etc. Están basados
en el sistema de calendario ISO, que sigue las reglas del calendario
Gregoriano e incluyen soporte automático para cosas como años
bisiestos, zonas horarias y cambio automático de zona horaria.
Las clases Date y Calendar no son muy adecuadas
para el manejo de fechas . Están mal diseñadas, abusan del uso de
enumeraciones y constantes. La posterior adición de la
clase java.sql.Date, pensada para facilitar su uso con bases de datos
JDBC no mejoró la cosa, ya que es una subclase de java.util.Date y,
por lo tanto, adolece de los mismos problemas.
Entonces, ¿cuál es la mejor manera de gestionar fechas en java?
JAVA.TIME.
MÉTODOS
 LocalDate: representa a fechas sin la hora y nos facilita su manejo
para comparar, declarar, sumar y restar fechas.
 LocalTime: es idéntica a la anterior pero para el manejo de horas,
sin ninguna fecha asociada.
 LocalDateTime: es una combinación de las dos anteriores, que
permite hacer lo mismo con fechas y horas simultáneamente.
 Instant: Se usa para almacenar un punto determinado en el
tiempo, o sea con fecha y hora, pero guarda su valor como
un timestamp de UNIX, es decir, en nanosegundos desde el epoch de
UNIX (1/1/1970 a las 00:00) y usando la zona horaria UTC.
 ZonedDateTime: esta clase es como LocalDateTime pero teniendo
en cuenta una zona horaria concreta, a diferencia de las anteriores.
 Period: esta clase auxiliar nos ayuda a obtener diferencias entre
fechas en distintos periodos (segundos, minutos, días...) y también a
añadir esas diferencias a las fechas.
 Duration: parecida a Period pero SOLO para manejo de horas.
JAVA.TIME
- ENUMERADOS
También incluye 2 Enumerados: de mes y de día de la semana
 java.time.DayOfWeek, es un Enum donde se definen todos los días de la
semana.
DayOfWeek lunes = DayOfWeek.MONDAY;
Este enum tiene algunos métodos interesantes que permite manipular días hacía
adelante y hacia atrás: plus() y minus(), respectivamente:
Además, con el método getDisplayName() se puede acceder al texto
que corresponde a la fecha, dependiendo del Locale actual, o indicado:
DayOfWeek lunes = DayOfWeek.MONDAY;
Locale l = new Locale("es",“ES");
System.out.println("TextStyle.FULL:" + lunes.getDisplayName(TextStyle.FULL, l));
System.out.println("TextStyle.NARROW:" + lunes.getDisplayName(TextStyle.NARROW, l));
System.out.println("TextStyle.SHORT:" + lunes.getDisplayName(TextStyle.SHORT, l));
JAVA.TIME
- ENUMERADOS
 java.time.Month: Enum donde se definen todos los meses del año.
.. y el resultado sería así:
JAVA.TIME
- LOCALDATE
: manejan la fecha, pero, a diferencia del java.util.Date,
no maneja la hora.
nos facilita su manejo para declararlas, sumar y restar fechas y
compararlas..
: se crea un objeto LocalDate haciendo uso de los
métodos
 of(int year, int month, int dayOfMonth) :
LocalDate date = LocalDate.of(1989, 11, 11); //19891111
System.out.println(date.getYear()); //1989
System.out.println(date.getMonth()); //NOVEMBER
System.out.println(date.getDayOfMonth()); //11
También, se puede hacer uso del enum Month para dar legibilidad al
Código: LocalDate date = LocalDate.of(1989, Month.NOVEMBER, 11);
 now() : LocalDate date = LocalDate.now(); //Fecha actual
JAVA.TIME
- LOCALDATE
: Haciendo uso de los métodos withYear(int year) ,
withMonth(int month) , withDayOfMonth(int dayOfMonth) ,
with(TemporalField field, long newValue) se puede modificar el
LocalDate .
:
LocalDate date = LocalDate.of(2016, Month.JULY, 25); //20160725
LocalDate date1 = date.withYear(2017); //20170725
LocalDate date2 = date.withMonth(8); //20160825
LocalDate date3 = date.withDayOfMonth(27); //20160727
LocalDate date4 = date.with(ChronoField.MONTH_OF_YEAR, 9);
//20160925
NOTA: Si en el último ejemplo usamos ChronoField.HOUR_OF_DAY la
siguiente excepción será lanzada:
java.time.temporal.UnsupportedTemporalTypeException: Unsupported
unit: HourOfDay .
YEARMONTH-MONTHDAY-YEAR
java.time.YearMonth representa el mes de un año específico y podemos
obtener cuantos días tiene ese mes, útil para averiguar años bisiestos:
YearMonth mes = YearMonth.now();
System.out.printf("Este mes es %s y tiene %d días%n", mes, mes.lengthOfMonth());
mes = YearMonth.of(2004, Month.FEBRUARY);
System.out.printf("El mes %s tuvo %d días,%n", mes, mes.lengthOfMonth());
mes = YearMonth.of(2002, Month.FEBRUARY);
System.out.printf("el mes %s tuvo %d días,%n", mes, mes.lengthOfMonth());
mes = YearMonth.of(2000, Month.FEBRUARY);
System.out.printf("el mes %s tuvo %d días%n", mes, mes.lengthOfMonth());
mes = YearMonth.of(1800, Month.FEBRUARY);
System.out.printf("Pero el mes %s tuvo %d días ¿Sabías que no es considerado
bisiesto?%n",
mes, mes.lengthOfMonth());
java.time.MonthDay representa a un día de un mes en particular:
MonthDay dia=MonthDay.of(Month.FEBRUARY, 29);
System.out.printf("El día %s %s es válido para el año 2010%n",dia,dia.isValidYear(2010)?"":"no");
java.util.Year permite manipular y conocer sobre un año en específico:
Year año = Year.now();
System.out.printf("Este año es %s y %s es bisiesto%n", año, año.isLeap() ? "sí" : "no");
JAVA.TIME
- LOCALTIME
: representa un tiempo determinado.
se crea un objeto LocalTime haciendo uso de los
métodos: teniendo en cuenta la hora y minuto; hora, minuto y segundo y
finalmente hora, minuto, segundo y nanosegundo. :
 of(int hour, int minute, int second, int nano)
 of(int hour, int minute, int second)
 of(int hour, int minute)
LocalTime time = LocalTime.of(5, 30, 45, 35); //05:30:45:35
 now(): captura el LocalTime actual.
LocalTime ahora = LocalTime.now();
System.out.printf(“Justo ahora son las %d horas, %d minutos y %d
segundos\n", ahora.getHour(), ahora.getMinute(), ahora.getSecond());
JAVA.TIME
- LOCALTIME
: Haciendo uso de los métodos withHour(int hour) ,
withMinute(int minute) , withSecond(int second) , withNano(int
nanoOfSecond) se puede modificar el LocalTime .
:
LocalTime time = LocalTime.of(14, 30, 35); //14:30:35
LocalTime time1 = time.withHour(20); //20:30:35
LocalTime time2 = time.withMinute(25); //14:25:35
LocalTime time3 = time.withSecond(23); //14:30:23
LocalTime time4 = time.withNano(24); //14:30:35.000000024
LocalTime time5 = time.with(ChronoField.HOUR_OF_DAY, 23);
//23:30:35
NOTA: Si en el último ejemplo usamos chronoField.MONTH_OF_YEAR
la siguiente excepción será lanzada:
java.time.temporal.UnsupportedTemporalTypeException: Unsupported
unit: MonthOfYear
JAVA.TIME
- LOCALDATETIME
: es una clase compuesta, la cual combina las clases
anteriormente mencionadas LocalDate y LocalTime.
Haciendo uso del método of() y de todos los
campos (año, mes, día, hora, minuto, segundo, nanosegundo), esta clase
puede crear un objeto LocalDateTime basado en los tipos LocalDate y
LocalTime:
LocalDateTime dateTime = LocalDateTime.of(1989, 11, 11, 5, 30, 45, 35);
//1989-11-11T05:30:45.000000035
Para capturar el LocalDateTime actual se puede usar el método now() :
LocalDateTime dateTime = LocalDateTime.now();
NOTA: Estos objetos no tienen ninguna información relacionada al
timezone.
JAVA.TIME
- LOCALDATETIME
: Los métodos withYear(int year), withMonth(int
month), withDayOfMonth(int dayOfMonth), with(TemporalField field,
long newValue), withHour(int hour), withMinute(int minute),
withSecond(int second), withNano(int nanoOfSecond) pueden modificar
el LocalDateTime .
:
LocalDateTime dateTime = LocalDateTime.of(2016, Month.JULY,25, 22, 11, 30);
LocalDateTime dateTime1 = dateTime.withYear(2017);
LocalDateTime dateTime2 = dateTime.withMonth(8);
LocalDateTime dateTime3 = dateTime.withDayOfMonth(27);
LocalDateTime dateTime4 = dateTime.withHour(20);
LocalDateTime dateTime5 = dateTime.withMinute(25);
LocalDateTime dateTime6 = dateTime.withSecond(23);
LocalDateTime dateTime7 = dateTime.withNano(24);
LocalDateTime dateTime8 = dateTime.with(ChronoField.HOUR_OF_DAY, 23);
JAVA.TIME
- INSTANT
: representa el número de segundos desde 1 de Enero de
1970 . Es un modelo de fecha y tiempo fácil de interpretar para una
máquina.
Haciendo uso del método ofEpochSecond() se
puede crear un objeto Instant:
Instant instant = Instant.ofEpochSecond(120); // 1970-01-01T00:02:00Z
Para capturar el Instant actual se puede usar el método now() :
Instant instant = Instant.now();
Cuyo resultado es: 2021-01-23T15:18:19.648561800Z
JAVA.TIME
- DURATION
: hace referencia a la diferencia que existe entre dos
objetos de tiempo: LocalTime o LocalDateTime.
Haciendo uso del método of (long amount,
TemporalUnit unit) se puede crear un objeto Duration, por ejemplo
de días, aunque el uso del enum ChronoUnit brinda una serie de
unidades de períodos de tiempo (YEARS, MONTHS, WEEKS, etc.:
Duration oneDayDuration = Duration.of(1, ChronoUnit.DAYS);
Ejemplo, la duración se calcula haciendo uso de dos objetos LocalTime :
LocalTime localTime1 = LocalTime.of(12, 25);
LocalTime localTime2 = LocalTime.of(17, 35);
Duration duration = Duration.between(localTime1, localTime2);
Duration se basa en los métodos ofDays(long days), ofHours(long
hours), ofMilis(long milis), ofMinutes(long minutes),
ofNanos(long nanos) , ofSeconds(long seconds). Aplicado al
ejemplo anterior: Duration oneDayDuration = Duration.ofDays(1);
JAVA.TIME
- PERIOD
: referencia a la diferencia que existe entre dos fechas.
LocalDate localDate1 = LocalDate.of(2016, Month.JULY, 18);
LocalDate localDate2 = LocalDate.of(2016, Month.JULY, 20);
Period period = Period.between(localDate1, localDate2);
Haciendo uso del método of(int years, int
months, int days) se puede crear un periodo. Por ejemplo, para crear
un período de 1 año 2 meses y 3 días :
Period period = Period.of(1, 2, 3);
Del mismo modo que Duration , se puede crear Period basado en los
métodos ofDays(int days) , ofMonths(int months) , ofWeeks(int
weeks) , ofYears(int years):
Period period = Period.ofYears(1);
PAQUETE JAVA.TIME
Construyendo fechas y horas con java.time:
Estas clases producen instancias inmutables, al contrario de lo que
pasaba con las antiguas clases Date de Java, por lo que dado que
carecen de constructores públicos, se instancian usando métodos de
tipo "factoría", es decir, tienen métodos que construyen estas clases a
partir de posibles parámetros que le pasemos.
En concreto, todas las de manejo de fechas y horas disponen de tres
métodos importantes, que son:
 now(): crean instancias nuevas a partir de la fecha y hora actual.
 of(): construyen fechas y horas a partir de sus partes.
 with(): modifican la fecha u hora actual en función del parámetro
que se le pase, con alguna cantidad (años, días, horas...) o
alguna clase de ajuste.
MÉTODOS JAVA.TIME-OF()
En el caso de LocalDateTime también le podríamos haber pasado la
hora llegando hasta los nanosegundos, en sucesivos parámetros:
System.out.println( "Con la hora exacta: " + LocalDateTime.of(1972,
Month.MAY, 23, 20, 01, 15, 0023) ); que incluiría la hora exacta. Este
método tiene varias sobrecargas, por lo que, por ejemplo, le podríamos
haber pasado también dos parámetros, uno con la fecha y otro con la
hora usando sendas clases LocalDate y LocalTime.
Si intentas pasar una fecha incorrecta al método factoría se produce
una excepción. Por ejemplo, al usar el día 29 de febrero de 2019:
MÉTODOS JAVA.TIME-GET()
Partes de una fecha o una hora
Es posible extraer cualquier parte de una fecha o una hora a través
de los métodos getXXX() que ofrecen estas clases. Por
ejemplo, getHour(), getMinute(), getMonth() o getDayOfWeek().
Gracias a ellos podemos extraer cualquier parte de una fecha para
trabajar con ella.
JAVA.TIME-OPERACIONES
LOCALDATE
Realizar operaciones como suma o resta de días, meses, años, etc es
muy fácil con la nueva Date API . Los siguientes métodos proveen
una manera general de realizar estas operaciones:
 plus(long amountToAdd, TemporalUnit unit),
 minus(long amountToSubtract, TemporalUnit unit)
LocalDate date = LocalDate.of(2016, Month.JULY, 18);
LocalDate datePlusOneDay = date.plus(1, ChronoUnit.DAYS);
LocalDate dateMinusOneDay = date.minus(1, ChronoUnit.DAYS);
LocalDate datePlusOneMonth = date.plus(1, ChronoUnit.MONTHS);
LocalDate dateMinusOneYear = date.minus(1, ChronoUnit.YEARS);
También se puede hacer cálculos basados en un Period. Ejemplo:
LocalDate date = LocalDate.of(2016, Month.JULY, 18);
LocalDate datePlusOneDay = date.plus(Period.ofDays(1));
LocalDate dateMinusOneDay = date.minus(Period.ofDays(1));
JAVA.TIME-OPERACIONES
LOCALDATE Y LOCALTIME
Finalmente, haciendo uso de los siguientes métodos explícitos, se
puede indicar el valor a incrementar o reducir, según la siguiente
sintaxis  plusX(long xToAdd) o minusX(long xToSubtract):
:
plusDays() / minusDays(): para sumar o restar días a la fecha.
plusWeeks() / minusWeeks(): ídem con semanas.
plusMonths() / minusMonths(): para añadir o quitar meses.
plusYears() / minusYears(): para sumar o restar años.
plusNanos() / minusNanos(): para sumar o restar nanosegundos
plusSeconds() / minusSeconds(): para sumar o restar segundos
plusMinutes() / minusMinutes(): para sumar o restar minutos
plusHours() / minusHours(): para sumar o restar horas
JAVA.TIME-OPERACIONES
COMPARACIÓN
Métodos como isBefore , isAfter , isEqual están disponibles para
comparar las siguientes clases LocalDate , LocalTime y
LocalDateTime .
LocalDate date1 = LocalDate.of(2016, Month.JULY, 28);
LocalDate date2 = LocalDate.of(2016, Month.JULY, 29);
boolean isBefore = date1.isBefore(date2); //true
boolean isAfter = date2.isAfter(date1); //true
boolean isEqual = date1.isEqual(date2); //false
PAQUETE JAVA.TIME
TIEMPO TRANSCURRIDO
Para obtener la diferencia entre dos fechas u horas, o sea, el
tiempo transcurrido entre dos instantes de tiempo, disponemos de:
1. una interfaz java.time.temporal.TemporalUnit,
2. una enumeración ChronoUnit y
3. una clase Period
Con sus métodos:
1. between(): tiempo transcurrido entre dos instantes de tiempo
2. until() tiempo que falta para llegar a una fecha u hora
determinadas.
Por ejemplo, para saber el tiempo transcurrido entre dos fechas:
JAVA.TIME-TEMPORALADJUSTERS
Existe una clase factoría llamada TemporalAdjusters (en plural) cuyos métodos
permiten hacer ajustes de fecha (de la clase TemporalAdjuster) para obtener
nuevas fechas a partir de una existente.
LocalDate , LocalTime y LocalDateTime proveen los siguientes métodos:
 with(TemporalField field, long newValue)
 with(TemporalAdjuster adjuster)
El primero de ellos ha sido revisado en los ejemplos anteriores. El segundo
brinda una serie de métodos que son útiles para cálculos.
import static java.time.temporal.TemporalAdjusters.next;
import static java.time.temporal.TemporalAdjusters.firstDayOfNextMonth;
import static java.time.temporal.TemporalAdjusters.lastDayOfMonth;
LocalDateTime dateTime = LocalDateTime.of(2016, Month.JULY, 25, 22, 11, 30);
LocalDateTime dateTime1 = dateTime.with(next(DayOfWeek.SUNDAY)); (1)
LocalDateTime dateTime2 = dateTime.with(firstDayOfNextMonth()); (2)
LocalDateTime dateTime3 = dateTime.with(lastDayOfMonth()); (3)
1. Retorna el próximo Domingo.
2. Retorna el primer día del siguiente mes (Agosto).
3. Retorna el último día del mes (actual).
JAVA.TIME-TEMPORALADJUSTERS
Para obtener el primer día del mes de una determinada fecha usaremos el
método TemporalAdjusters.firstDayOfMonth(). Del mismo modo existen
"ajustadores" para otras operaciones similares.
Así, para averiguar la fecha del primer día del mes que viene, podemos escribir:
System.out.println("El primer día del próximo mes es: " + LocalDate.now().with(
TemporalAdjusters.firstDayOfNextMonth() ).getDayOfWeek() );
Utilizar el método with() de las clases de , que en este caso toma un ajustador
para obtener el primer día del mes siguiente. Luego usamos el método
getDayOfWeek() sobre la fecha resultante para saber qué día de la semana es.
O para saber la fecha del último día del mes actual:
System.out.println("El último día de este mes es: " + LocalDate.now().with(
TemporalAdjusters.lastDayOfMonth() ));
Por supuesto, como lo que devuelven son objetos de tiempo, se pueden combinar
con las funciones plusXXX() y minusXXX() para hacer más operaciones.
Es importante señalar que, se pueden crear nuestros propios ajustadores
temporales con tan solo implementar una interfaz.
JAVA.TIME-TEMPORALADJUSTERS
TemporalAdjuster es una FunctionalInterface , eso quiere decir que se puede
crear una implementación propia haciendo uso de lambdas.
LocalDateTime dateTime = LocalDateTime.of(2016, Month.JULY, 28, 22, 11, 30);
TemporalAdjuster tempAdj=temp>nextDayAfterHolidays(LocalDateTime.from(t
emp));
LocalDateTime dateTime1 = dateTime.with(tempAdj);
public Temporal nextDayAfterHolidays(LocalDateTime dateTime) {
LocalDate[] holidays = {
LocalDate.of(2016, Month.JULY, 28),
LocalDate.of(2016, Month.JULY, 29)
};
LocalDate date = dateTime.toLocalDate();
boolean isHoliday = Arrays.stream(holidays)
.anyMatch(holiday >
holiday.isEqual(date));
if (isHoliday) {
return nextDayAfterHolidays(dateTime.plus(1, ChronoUnit.DAYS));
}
return dateTime;
}
JAVA.TIME-FORMATO
Pasear una fecha es interpretarlas a partir de una cadena, generalmente recibida de
la entrada de un usuario o de algún sistema de almacenamiento externo.
El método parse() se ocupa de esto de manera trivial. Tiene dos sobrecargas, una que
recibe la cadena a interpretar y, una segunda que además añade un formateador
especializado si lo necesitamos:
LocalDate hoy = LocalDate.parse("2020-07-06"); //Se podría usar también LocalDateTime
LocalDate seisNov = LocalDate.parse("6/11/2020", DateTimeFormatter.ofPattern("d/M/yyyy") );
(donde ofPattern() es un método factoría para obtener un formateador a partir
de
una
cadena
basada
en
letras
estándar
para
formato).
https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html#patterns
El método format(), convierte una clase temporal en una cadena de texto usando el
formato que nos interese.
LocalDateTime fechaConHora = LocalDateTime.parse(“2021-01-26T08:40:15”);
System.out.println("Formato por defecto: " + fechaConHora);
System.out.println("Formato ISO 8601 (explícito): " +
fechaConHora.format(DateTimeFormatter.ISO_DATE_TIME));
DateTimeFormatter esDateFormat = DateTimeFormatter.ofPattern("dd/MM/yyyy hh:mm:ss");
System.out.println("Formato español (manual): " + fechaConHora.format(esDateFormat));
A continuación veremos diversos formateadores ya predefinidos en forma de constantes
de DateTimeFormatter.
JAVA.TIME-FORMATO
JAVA.TIME-FORMATO
Si queremos formatear una fecha del siguiente estilo:
“Lunes, 26 de Enero de 2021 a las 08:45:00 horas”,
lo haremos usando la clase java.time.format.DateTimeFormatter:
DateTimeFormatter esDateFormatLargo = DateTimeFormatter
.ofPattern("EEEE, dd 'de' MMMM 'de' yyyy 'a las' hh:mm:ss ‘horas’") //"escapeamos"
todos los fragmentos que no son formato usando una comilla simple.
.withLocale(new Locale("es", "ES"));
System.out.println("Formato español (largo, localizado): " +
fechaConHora.format(esDateFormatLargo));
Para formatear la fecha con el formato actual del usuario de la aplicación, tenemos que
averiguar el idioma y país del usuario actual.
String idiomaLocal = System.getProperty("user.language");
String paisLocal = System.getProperty("user.country");
System.out.println("Formato actual del sistema (" + idiomaLocal + "-" + paisLocal + "): " +
fechaConHora.format( DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT)
.withLocale( new Locale(idiomaLocal, paisLocal) ) ) );
NOTA: usamos el valor SHORT de la enumeración FormatStyle para expresar de manera
genérica el formato corto de fecha y hora. En este caso no podríamos haber usado el formato
largo (LONG) ni completo (FULL) porque necesitan la información de zona horaria, que
nuestra fecha de ejemplo no tiene por ser un LocalDateTime y no un ZonedDateTime.
Descargar