Está en la página 1de 19

¡Empieza Por Aquí!

Artículos 
Caja De Herramientas 
Sobre Mí 

Fechas en Java: LocalDate, LocalTime y


LocalDateTime

La gestión del tiempo en Java, utilizando las clases LocalDate, LocalTime y LocalDateTime, es una novedad de la versión 8.
Antes de empezar, recuerda que en el examen de certificación OCAJ8P no están incluidas las zonas horarias. Esto facilita
bastante las cosas pero, como ya te dije en el artículo anterior, el examen va a intentar ponerte trampas.

¿Qué vas a aprender en este artículo?

Las clases relativas al tiempo en Java tienen su propio paquete Cómo darle formato a una fecha/hora sin liarte

¡Recuerda!  Formato ISO Privacidad - Términos


¡Nunca mezcles las clases relativas al tiempo en Java! Formato .ofLocalizedDate/Time/DateTime

Period solo acepta el último método Formato arbitrario .ofPattern

Ejemplo de línea de formato arbitrario con error (puntos 1 y 2)

Ejemplo de combinación rara (puntos 3 y 4)

BONUS: método .parse

Ejercicio recomendado

Las clases relativas al tiempo en Java tienen su propio


paquete
Esto es algo muy importante ya que, sin importar el paquete, el código no puede compilar. De este modo, si en el examen
aparece un fragmento de código y falta el import correspondiente, ya sabes cuál es la consecuencia.

1 package es.javautodidacta;
2
3 import java.time.*; // Este paquete contiene LocalDate, LocalTime y LocalDateTime.
4 import java.time.format.*; // Este paquete contiene DateTimeFormatter.
5
6 public class Fechas {
7
8 public static void main(String[] args) {
9 LocalTime ahora = LocalTime.now();
Privacidad - Términos
10 System.out.println(ahora);
11 }
12 }

Fechas.java
hosted with ❤ by GitHub view raw

¡Recuerda! 

El paquete java.time contiene las clases relativas al tiempo (LocalDate, LocalTime y LocalDateTime).

El paquete java.time.format contiene la clase DateTimeFormatter.

Si en el código que te aparezca en el examen aparecen fechas u horas, ha de importarse java.time.

Si, además de aparecer, el código las formatea, han de importarse ambos paquetes (java.time y java.time.format).

¡Nunca mezcles las clases relativas al tiempo en Java!


Las clases LocalDate, LocalTime y LocalDateTime no mantienen relación alguna de herencia. Esto quiere decir que no puedes
hacer uso del polimorfismo. Por ello, una referencia de tipo LocalDateTime no puede apuntar a un objeto de tipo LocalDate,
por ejemplo. Te lo muestro en el siguiente ejemplo:

Privacidad - Términos
1 package es.javautodidacta;
2
3 import java.time.*; // Este paquete contiene LocalDate, LocalTime y LocalDateTime.
4 import java.time.format.*; // Este paquete contiene DateTimeFormatter.
5
6 public class Fechas {
7
8 public static void main(String[] args) {
9 LocalTime ahora = LocalDate.now();
10 System.out.println(ahora);
11
12 LocalDateTime ahora2 = LocalDate.now();
13 System.out.println(ahora2);
14 }
15 }
16
17 /*
18 * Fechas.java:9: error: incompatible types: LocalDate cannot be converted to LocalTime
19 * Fechas.java:12: error: incompatible types: LocalDate cannot be converted to LocalDateTime
20 */

Fechas.java
hosted with ❤ by GitHub view raw

Como ves, las clases relativas al tiempo en Java utilizan siempre métodos estáticos, que devuelven una referencia del tipo de
la clase que se ha utilizado para ejecutarlos. Eso quiere decir que si estás utilizando una referencia de tipo LocalDate, tienes
que usar LocalDate.now() para instanciarla.

Si no lo haces, el código no va a compilar, porque LocalDate.now() es incompatible con una referencia de tipo LocalTime. Y
LocalDateTime es incompatible con ambos.
Privacidad - Términos
Lo que sí puedes hacer es crear un objeto de tipo LocalDateTime a partir de un objeto de tipo LocalDate y de otro LocalTime
(¡en este orden!). Lo que no puedes hacer es apuntar la referencia de una de estas clases a un objeto de otra.

1 package es.javautodidacta;
2
3 import java.time.*; // Este paquete contiene LocalDate, LocalTime y LocalDateTime.
4 import java.time.format.*; // Este paquete contiene DateTimeFormatter.
5
6 public class Fechas {
7
8 public static void main(String[] args) {
9 LocalDate hoy = LocalDate.now();
10 LocalTime ahora = LocalTime.now();
11
12 LocalDateTime fecha = LocalDateTime.of(hoy, ahora);
13
14 System.out.println(fecha);
15 }
16 }
17
18 /*
19 * Resultado: 2018-02-27T12:26:30.107
20 */

Fechas.java
hosted with ❤ by GitHub view raw

No existe otra manera de instanciar alguna de las clases relativas al tiempo en Java, ya que sus constructores son privados.
No olvides que los métodos estáticos pueden utilizarse tanto con el nombre de la clase, como con una instancia de dicha
clase, aunque esta no apunte a ningún objeto (valor null): Privacidad - Términos
1 package es.javautodidacta;
2
3 import java.time.*; // Este paquete contiene LocalDate, LocalTime y LocalDateTime.
4 import java.time.format.*; // Este paquete contiene DateTimeFormatter.
5
6 public class Fechas {
7
8 public static void main(String[] args) {
9 LocalTime vacio = null;
10 LocalTime noNull = vacio.now();
11 System.out.println(noNull);
12 }
13 }
14
15 /*
16 * Resultado: 11:13:33.801
17 */

Fechas.java
hosted with ❤ by GitHub view raw

Compila sin problema e imprime la hora actual.

Period solo acepta el último método


Como ya te he dicho antes, para instanciar las clases relativas al tiempo en Java se utilizan métodos estáticos. Period no es
una excepción. Lo único que tienes que tener en cuenta es que, al instanciar un objeto de tipo Period, Java solo tiene en
cuenta el último método estático que has utilizado: Privacidad - Términos
1 package es.javautodidacta;
2
3 import java.time.*; // Este paquete contiene LocalDate, LocalTime y LocalDateTime.
4 import java.time.format.*; // Este paquete contiene DateTimeFormatter.
5
6 public class Fechas {
7
8 public static void main(String[] args) {
9 LocalDate hoy = LocalDate.now();
10 Period periodo = Period.ofDays(4).ofDays(1);
11
12 // Fecha de hoy:
13 System.out.println("Hoy es: " + hoy);
14 // El periodo suma un solo día:
15 System.out.println("Tras sumar el periodo: " + hoy.plus(periodo));
16 }
17 }
18
19 /*
20 * Resultados:
21 * Hoy es: 2018-02-27
22 * Tras sumar el periodo: 2018-02-28
23 */

Fechas.java
hosted with ❤ by GitHub view raw

Recuerda que las fechas son inmutables. Eso quiere decir que, en el código anterior, el objeto al que apunta la referencia hoy
no se ve afectado por hoy.plus(periodo) si no lo reasignas.

Privacidad - Términos
Cómo darle formato a una fecha/hora sin liarte
El formato de las instancias de las clases relativas al tiempo en Java puede ser un poco lioso, así que vamos a ir paso a paso.
Estos son los tres tipos de formato que tienes que conocer:

Guarda esta chuleta

Formato ISO
El formato ISO hace referencia al estándar ISO 8601. Este es el formato predeterminado en las fechas/horas. Esto significa
que, al imprimirlas, vas a obtener una fecha/hora con este formato, aunque no se lo apliques.

No obstante, a la hora de aplicarlo, ten en cuenta lo siguiente:

ISO_LOCAL_DATE puede utilizarse con LocalDate y LocalDateTime (contienen una fecha). Privacidad - Términos
ISO_LOCAL_TIME puede utilizarse con LocalTime y LocalDateTime (contienen una hora).

ISO_LOCAL_DATE_TIME puede utilizarse solo con LocalDateTime (contiene una fecha y una hora).

Esto quiere decir que solo puedes utilizar un formato ISO si el objeto temporal al que lo aplicas contiene aquello que estás
formateando. LocalDateTime acepta los tres. La diferencia consiste en que, si imprimes el objeto LocalDateTime con el
formato ISO_LOCAL_TIME, vas a ver solo la hora que contiene. Si le aplicas ISO_LOCAL_DATE, va a imprimir solo la fecha:

1 package es.javautodidacta;
2
3 import java.time.*; // Este paquete contiene LocalDate, LocalTime y LocalDateTime.
4 import java.time.format.*; // Este paquete contiene DateTimeFormatter.
5
6 public class Fechas {
7
8 public static void main(String[] args) {
9
10 LocalDateTime fecha = LocalDateTime.now();
11
12 DateTimeFormatter isoFecha = DateTimeFormatter.ISO_LOCAL_DATE;
13 System.out.println(fecha.format(isoFecha));
14
15 DateTimeFormatter isoHora = DateTimeFormatter.ISO_LOCAL_TIME;
16 System.out.println(fecha.format(isoHora));
17 }
18 }
19
20 /*
Privacidad - Términos
21 * Resultados:
22 * 2018-02-27
23 * 16:58:40.62
24 */

Fechas.java
hosted with ❤ by GitHub view raw

Formato .ofLocalizedDate/Time/DateTime
En este caso, al igual que con el formato ISO, tienes que utilizar el que corresponda con la referencia temporal que estás
utilizando. Es decir, no utilices .ofLocalizedDate para formatear un objeto de tipo LocalTime.

Formato arbitrario .ofPattern


Este método de DateTimeFormatter acepta una String (cadena de texto). Así, podemos darle cualquier formato a un objeto
de tipo LocalDate, LocalTime o LocalDateTime. En la cadena de texto que utilizamos como patrón puede haber tres tipos de
elementos: 

Letras que simbolizan un elemento temporal. La lista completa está en la página web de Oracle.

Texto entre comillas simples, que aparece tal cual al imprimir.

Signos de puntuación.

Te lo muestro en el ejemplo que sigue:


Privacidad - Términos
1 package es.javautodidacta;
2
3 import java.time.*; // Este paquete contiene LocalDate, LocalTime y LocalDateTime.
4 import java.time.format.*; // Este paquete contiene DateTimeFormatter.
5
6 public class Fechas {
7
8 public static void main(String[] args) {
9
10 LocalTime hora = LocalTime.now();
11 DateTimeFormatter f = DateTimeFormatter.ofPattern("'Son las' h 'y' mm");
12 System.out.println(hora.format(f));
13 }
14 }
15
16 /*
17 * Resultado:
18 * Son las 5 y 27
19 */

Fechas.java
hosted with ❤ by GitHub view raw

Todas las letras están reservadas, tanto las mayúsculas como las minúsculas. Esto significa que, cuando se utilice el formato
.ofPattern en el examen, has de estar atento a los siguientes puntos:

 Al igual que en los casos anteriores, no puedes formatear una fecha en un objeto de tipo LocalTime, o una hora en un objeto

de tipo LocalDate. Si lo intentas, el código compilará pero la ejecución se detendrá con una excepción
Privacidad - Términos
(UnsupportedTemporalTypeException). Fíjate bien en el patrón que se utilice en el examen.

 En relación con el punto anterior, asegúrate de que el texto literal que aparezca en el patrón esté entre comillas simples.

 Algunos símbolos son similares, pero tienen significados muy distintos. Mientras que m minúscula equivale a "minuto", M

mayúscula equivale a "mes".

 En relación con el punto anterior, las combinaciones raras son válidas, aunque no debas utilizarlas tú en tu código.

Ejemplo de línea de formato arbitrario con error (puntos 1 y 2)

1 package es.javautodidacta;
2
3 import java.time.*; // Este paquete contiene LocalDate, LocalTime y LocalDateTime.
4 import java.time.format.*; // Este paquete contiene DateTimeFormatter.
5
6 public class Fechas {
7
8 public static void main(String[] args) {
9
10 LocalTime hora = LocalTime.now();
11 DateTimeFormatter f = DateTimeFormatter.ofPattern("'Son las' h y mm");
12 System.out.println(hora.format(f));
13 }
14 }
15
16 /*
17 * Resultado:
Privacidad - Términos

18 * Exception in thread "main" java.time.temporal.UnsupportedTemporalTypeException: Unsupported field: YearOfEra


19 */

Fechas.java
hosted with ❤ by GitHub view raw

La única diferencia con el ejemplo anterior es que he retirado las comillas simples que había en torno a la "y". Así, ha pasado
de ser texto literal a simbolizar YearOfEra. Como en este caso estoy formateando un objeto de tipo LocalTime, sin
información sobre el año, la ejecución se detiene con una excepción.

Ejemplo de combinación rara (puntos 3 y 4)

1 package es.javautodidacta;
2
3 import java.time.*; // Este paquete contiene LocalDate, LocalTime y LocalDateTime.
4 import java.time.format.*; // Este paquete contiene DateTimeFormatter.
5
6 public class Fechas {
7
8 public static void main(String[] args) {
9
10 LocalDateTime hora = LocalDateTime.now();
11 DateTimeFormatter f = DateTimeFormatter.ofPattern("hh:MM");
12 System.out.println("Hora:mes = " + hora.format(f));
13 }
14 }
15
16 /*
17 * Resultado: Hora:mes = 05:02
18 */

Privacidad - Términos

Fechas.java
hosted with ❤ by GitHub view raw
Si el examen te diese una fecha y hora completas, y te preguntase qué imprime este código, podrías caer en la trampa de
pensar que va a imprimir la hora y los minutos. Pero no: imprime la hora y el mes. Son las cinco de la tarde de un día de
febrero.

Échale un vistazo a la lista de símbolos en la página de Oracle y practícalos. Recuerda que, para el OCAJ8P, no es necesario
que practiques los símbolos relativos a las zonas horarias.

BONUS: método .parse


El método .parse se utiliza para crear un objeto de tipo LocalDate, LocalTime o LocalDateTime a partir de una cadena de
texto. El método .parse admite dos argumentos:

 El primer argumento se trata de la cadena de texto que vas a transformar en un objeto temporal.

 El segundo argumento se trata del objeto de tipo DateTimeFormatter con el que le vas a decir al método .parse cómo

aparece la fecha expresada en la cadena de texto, para que la entienda.

El segundo argumento, el formateador, puede ser cualquier formato que hemos visto más arriba: un ISO, un
.ofLocalizedDate/Time/DateTime o un patrón arbitrario. Lo importante es que el primer argumento se ha de corresponder
con el formato que vas a utilizar para "traducirlo" a una instancia de alguna clase relativa al tiempo en Java. Es por ello que
Privacidad - Términos
debes conocer el resultado de imprimir cada uno de los tipos de formato disponibles, y cuál es el significado de cada letra en
los formatos arbitrarios de .ofPattern.

Por último, .parse acepta un único argumento si la cadena de texto se corresponde con el formato ISO, el predeterminado.

1 package es.javautodidacta;
2
3 import java.time.*; // Este paquete contiene LocalDate, LocalTime y LocalDateTime.
4 import java.time.format.*; // Este paquete contiene DateTimeFormatter.
5
6 public class Fechas {
7
8 public static void main(String[] args) {
9
10 LocalDateTime hoy = LocalDateTime.parse("2018-02-27T18:14:01.184");
11 DateTimeFormatter f = DateTimeFormatter.ofPattern("'Hoy es' d 'del mes' M 'del año' yyyy. 'Son las' kk 'horas'.");
12 System.out.println(hora.format(f));
13 }
14 }
15
16 /*
17 * Resultado: Hoy es 27 del mes 2 del año 2018. Son las 18 horas.
18 */

Fechas.java
hosted with ❤ by GitHub view raw

Ejercicio recomendado Privacidad - Términos


Te recomiendo que practiques bien las fechas y las horas, cómo instanciarlas y cómo modificarlas. Además, no olvides que
tienes que dominar cómo formatear las fechas/horas para el examen. En mi opinión, el formato arbitrario (.ofPattern) es
donde el examen puede intentar ponértelo más difícil.


Miguel Callejón Berenguer 
Java, OCAJ8P

Artículos relacionados

Internacionalización y localización en Java Cómo exportar un proyecto JavaFX en IntelliJ

Privacidad - Términos
Curso gratuito de IntelliJ Community Edition Bucles do-while y while en Java
¡en español!

Deja una respuesta 0 comentarios

Deja una respuesta:


Nombre *

E-mail *

Página web


Save my name, email, and website in this browser for the next time I comment.

Privacidad - Términos
Responsable » Miguel Callejón Berenguer

Finalidad » gestionar los comentarios.

Legitimación » tu consentimiento.

Destinatarios » los datos que me facilitas estarán ubicados en los servidores de Webempresa (proveedor de hosting de JavAutodidacta)
dentro de la UE. Ver política de privacidad de Webempresa (https://www.webempresa.com/aviso-legal.html).

Derechos » podrás ejercer tus derechos, entre otros, a acceder, rectificar, limitar y suprimir tus datos dirigiéndote a
miguel@javautodidacta.es, así como el derecho a presentar una reclamación ante una autoridad de control.

Acepto la política de privacidad. *

ENVIAR COMENTARIO

Privacidad - Términos
←ARTÍCULO ANTERIOR ARTÍCULO SIGUIENTE→

Buscar... 
Aviso legal
Política de privacidad
Política de cookies
Contacto

JavAutodidacta © 2019

Privacidad - Términos

También podría gustarte