Java
Tutorial Java: LocalTime
Aprende a usar Java LocalTime para manipular horas, realizar cálculos temporales y formatear tiempos con ejemplos prácticos y avanzados.
Aprende Java y certifícateCreación y manipulación básica de tiempo sin fecha
La clase LocalTime
forma parte del paquete java.time
introducido en Java 8, y está diseñada específicamente para representar y manipular horas sin componente de fecha. Esta clase es inmutable y thread-safe, lo que la hace ideal para aplicaciones concurrentes.
A diferencia de las antiguas clases para manejo de tiempo como java.util.Date
, LocalTime
se centra exclusivamente en representar un momento del día, como "10:30:45", sin información sobre el día, mes o año.
Creación de objetos LocalTime
Existen varias formas de crear instancias de LocalTime
:
- 1. Obtener la hora actual del sistema:
// Obtiene la hora actual del sistema
LocalTime ahora = LocalTime.now();
System.out.println("Hora actual: " + ahora);
- 2. Crear una hora específica mediante valores de hora, minuto, segundo y nanosegundo:
// Hora y minutos
LocalTime desayuno = LocalTime.of(8, 30);
// Hora, minutos y segundos
LocalTime almuerzo = LocalTime.of(13, 0, 0);
// Hora, minutos, segundos y nanosegundos
LocalTime cena = LocalTime.of(21, 0, 0, 0);
System.out.println("Desayuno: " + desayuno);
System.out.println("Almuerzo: " + almuerzo);
System.out.println("Cena: " + cena);
- 3. Parsear una cadena de texto que represente una hora:
// Formato ISO-8601 (HH:mm:ss)
LocalTime hora1 = LocalTime.parse("15:30:45");
// Con un formateador personalizado
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH mm ss");
LocalTime hora2 = LocalTime.parse("20 30 00", formatter);
System.out.println("Hora parseada 1: " + hora1);
System.out.println("Hora parseada 2: " + hora2);
- 4. Obtener horas predefinidas:
// Hora mínima (00:00)
LocalTime minima = LocalTime.MIN;
// Hora máxima (23:59:59.999999999)
LocalTime maxima = LocalTime.MAX;
// Mediodía (12:00)
LocalTime mediodia = LocalTime.NOON;
// Medianoche (00:00)
LocalTime medianoche = LocalTime.MIDNIGHT;
System.out.println("Hora mínima: " + minima);
System.out.println("Hora máxima: " + maxima);
System.out.println("Mediodía: " + mediodia);
System.out.println("Medianoche: " + medianoche);
Acceso a componentes de tiempo
Podemos extraer los diferentes componentes de un objeto LocalTime
:
LocalTime tiempo = LocalTime.of(13, 45, 30, 123456789);
int hora = tiempo.getHour(); // 13
int minuto = tiempo.getMinute(); // 45
int segundo = tiempo.getSecond(); // 30
int nano = tiempo.getNano(); // 123456789
System.out.println("Hora: " + hora);
System.out.println("Minuto: " + minuto);
System.out.println("Segundo: " + segundo);
System.out.println("Nanosegundo: " + nano);
Manipulación básica de tiempo
Como LocalTime
es inmutable, cualquier operación de modificación devuelve una nueva instancia sin alterar la original:
- 1. Añadir o restar unidades de tiempo:
LocalTime ahora = LocalTime.of(15, 30);
// Añadir horas, minutos, segundos o nanosegundos
LocalTime masTarde = ahora.plusHours(2);
LocalTime masMinutos = ahora.plusMinutes(15);
LocalTime masSegundos = ahora.plusSeconds(30);
LocalTime masNanos = ahora.plusNanos(1000000);
// Restar unidades de tiempo
LocalTime masAntes = ahora.minusHours(1);
LocalTime menosMinutos = ahora.minusMinutes(10);
System.out.println("Hora original: " + ahora);
System.out.println("Dos horas más tarde: " + masTarde);
System.out.println("15 minutos más tarde: " + masMinutos);
System.out.println("Una hora antes: " + masAntes);
- 2. Modificar componentes específicos:
LocalTime tiempo = LocalTime.of(16, 30, 20);
// Cambiar componentes individuales
LocalTime nuevaHora = tiempo.withHour(20);
LocalTime nuevoMinuto = tiempo.withMinute(45);
LocalTime nuevoSegundo = tiempo.withSecond(0);
LocalTime nuevoNano = tiempo.withNano(0);
System.out.println("Tiempo original: " + tiempo);
System.out.println("Con hora cambiada: " + nuevaHora);
System.out.println("Con minuto cambiado: " + nuevoMinuto);
- 3. Truncar a una unidad específica:
LocalTime detallado = LocalTime.of(12, 34, 56, 789000000);
// Truncar a diferentes unidades
LocalTime soloHora = detallado.truncatedTo(ChronoUnit.HOURS); // 12:00
LocalTime hastaMinutos = detallado.truncatedTo(ChronoUnit.MINUTES); // 12:34
LocalTime hastaSegundos = detallado.truncatedTo(ChronoUnit.SECONDS); // 12:34:56
System.out.println("Tiempo original: " + detallado);
System.out.println("Truncado a horas: " + soloHora);
System.out.println("Truncado a minutos: " + hastaMinutos);
System.out.println("Truncado a segundos: " + hastaSegundos);
Consultas sobre el tiempo
LocalTime
proporciona métodos para realizar consultas sobre el valor del tiempo:
LocalTime tiempo = LocalTime.of(14, 30);
// Comprobar si un tiempo está antes o después de otro
boolean esAntes = tiempo.isBefore(LocalTime.of(15, 0)); // true
boolean esDespues = tiempo.isAfter(LocalTime.NOON); // true
// Comprobar si es mediodía o medianoche
boolean esMediodia = tiempo.equals(LocalTime.NOON); // false
boolean esMedianoche = tiempo.equals(LocalTime.MIDNIGHT); // false
System.out.println("¿14:30 es antes de las 15:00? " + esAntes);
System.out.println("¿14:30 es después del mediodía? " + esDespues);
Ejemplo práctico: Control de horarios
Un ejemplo práctico de uso de LocalTime
podría ser un sistema de control de horarios laborales:
public class ControlHorario {
public static void main(String[] args) {
// Definir horarios laborales
LocalTime inicioJornada = LocalTime.of(9, 0);
LocalTime finJornada = LocalTime.of(18, 0);
LocalTime inicioDescanso = LocalTime.of(13, 0);
LocalTime finDescanso = LocalTime.of(14, 0);
// Registrar entrada de un empleado
LocalTime horaEntrada = LocalTime.of(8, 45);
// Comprobar si ha llegado a tiempo
if (horaEntrada.isAfter(inicioJornada)) {
System.out.println("Empleado ha llegado tarde");
// Calcular minutos de retraso
long minutosRetraso = ChronoUnit.MINUTES.between(inicioJornada, horaEntrada);
System.out.println("Minutos de retraso: " + minutosRetraso);
} else {
System.out.println("Empleado ha llegado a tiempo");
// Calcular minutos de antelación
long minutosAntelacion = ChronoUnit.MINUTES.between(horaEntrada, inicioJornada);
System.out.println("Minutos de antelación: " + minutosAntelacion);
}
// Comprobar si una hora está dentro del horario laboral (excluyendo descanso)
LocalTime horaConsulta = LocalTime.of(15, 30);
boolean enHorarioLaboral = (horaConsulta.isAfter(inicioJornada) && horaConsulta.isBefore(finJornada))
&& !(horaConsulta.isAfter(inicioDescanso) && horaConsulta.isBefore(finDescanso));
System.out.println("¿Está en horario laboral? " + enHorarioLaboral);
}
}
Este ejemplo muestra cómo LocalTime
puede utilizarse para gestionar horarios y calcular diferencias de tiempo, sin preocuparse por componentes de fecha.
Cálculos, comparación y operaciones con LocalTime
La clase LocalTime
no solo nos permite representar momentos del día, sino que también ofrece un conjunto completo de operaciones para realizar cálculos temporales, comparaciones y otras manipulaciones avanzadas. Estas funcionalidades son fundamentales cuando necesitamos trabajar con horarios en aplicaciones como sistemas de reservas, planificadores o cualquier software que requiera lógica basada en horas.
Comparación entre instancias de LocalTime
Para determinar el orden cronológico entre dos horas, LocalTime
proporciona varios métodos de comparación:
LocalTime primeraTarea = LocalTime.of(9, 30);
LocalTime segundaTarea = LocalTime.of(11, 15);
LocalTime terceraTarea = LocalTime.of(9, 30);
// Comparación con métodos específicos
boolean esAnterior = primeraTarea.isBefore(segundaTarea); // true
boolean esPosterior = segundaTarea.isAfter(primeraTarea); // true
// Comparación de igualdad
boolean sonIguales = primeraTarea.equals(terceraTarea); // true
System.out.println("¿Primera tarea es anterior a segunda? " + esAnterior);
System.out.println("¿Segunda tarea es posterior a primera? " + esPosterior);
System.out.println("¿Primera y tercera tarea son a la misma hora? " + sonIguales);
También podemos utilizar el método compareTo()
que devuelve un valor entero:
LocalTime hora1 = LocalTime.of(14, 30);
LocalTime hora2 = LocalTime.of(16, 45);
int resultado = hora1.compareTo(hora2);
// resultado < 0 significa que hora1 es anterior a hora2
// resultado = 0 significa que son iguales
// resultado > 0 significa que hora1 es posterior a hora2
String relacion = (resultado < 0) ? "anterior a" :
(resultado > 0) ? "posterior a" : "igual a";
System.out.println("La hora " + hora1 + " es " + relacion + " la hora " + hora2);
Cálculo de periodos entre horas
Para calcular la duración entre dos instancias de LocalTime
, podemos utilizar la clase ChronoUnit
o la clase Duration
:
- Usando ChronoUnit para cálculos simples:
LocalTime inicio = LocalTime.of(8, 15);
LocalTime fin = LocalTime.of(10, 45);
// Calcular diferencia en distintas unidades
long diferenciaHoras = ChronoUnit.HOURS.between(inicio, fin); // 2
long diferenciaMinutos = ChronoUnit.MINUTES.between(inicio, fin); // 150
long diferenciaSegundos = ChronoUnit.SECONDS.between(inicio, fin); // 9000
System.out.println("Diferencia en horas: " + diferenciaHoras);
System.out.println("Diferencia en minutos: " + diferenciaMinutos);
System.out.println("Diferencia en segundos: " + diferenciaSegundos);
- Usando Duration para cálculos más complejos:
LocalTime inicioClase = LocalTime.of(9, 0);
LocalTime finClase = LocalTime.of(10, 30);
// Crear un objeto Duration
Duration duracionClase = Duration.between(inicioClase, finClase);
// Extraer componentes de la duración
long horas = duracionClase.toHours(); // 1
long minutos = duracionClase.toMinutes(); // 90
long segundos = duracionClase.getSeconds(); // 5400
long minutosRestantes = duracionClase.toMinutesPart(); // 30
System.out.println("Duración de la clase: " + duracionClase);
System.out.println("Horas: " + horas);
System.out.println("Minutos totales: " + minutos);
System.out.println("Minutos (parte): " + minutosRestantes);
Manejo de horas que cruzan la medianoche
Un aspecto importante a considerar es que LocalTime
representa un momento del día en un ciclo de 24 horas. Cuando calculamos duraciones que cruzan la medianoche, debemos tener cuidado:
LocalTime inicioTurno = LocalTime.of(22, 0); // 10:00 PM
LocalTime finTurno = LocalTime.of(6, 0); // 6:00 AM del día siguiente
// Cálculo incorrecto (resultado negativo)
long horasDirectas = ChronoUnit.HOURS.between(inicioTurno, finTurno); // -16
// Solución: ajustar manualmente
long horasCorrectas = (horasDirectas < 0) ? horasDirectas + 24 : horasDirectas; // 8
System.out.println("Horas de turno (cálculo directo): " + horasDirectas);
System.out.println("Horas de turno (corregido): " + horasCorrectas);
Una alternativa más robusta es utilizar LocalDateTime
cuando necesitamos manejar periodos que cruzan la medianoche, pero si queremos mantenernos en el ámbito de LocalTime
, podemos implementar esta lógica:
public static long horasEntreTiempos(LocalTime inicio, LocalTime fin) {
if (fin.isBefore(inicio) || fin.equals(inicio)) {
// Si fin es antes que inicio, asumimos que cruza la medianoche
return ChronoUnit.HOURS.between(inicio, fin.plus(1, ChronoUnit.DAYS));
} else {
return ChronoUnit.HOURS.between(inicio, fin);
}
}
Operaciones aritméticas con Duration
Podemos combinar LocalTime
con Duration
para realizar operaciones aritméticas más complejas:
LocalTime horaInicio = LocalTime.of(10, 15);
// Crear una duración
Duration duracion = Duration.ofHours(2).plusMinutes(30); // 2 horas y 30 minutos
// Sumar la duración a la hora de inicio
LocalTime horaFin = horaInicio.plus(duracion); // 12:45
// Restar una duración
LocalTime horaAnterior = horaInicio.minus(Duration.ofMinutes(45)); // 9:30
System.out.println("Hora de inicio: " + horaInicio);
System.out.println("Duración: " + duracion);
System.out.println("Hora de finalización: " + horaFin);
System.out.println("45 minutos antes de la hora de inicio: " + horaAnterior);
También podemos sumar y restar duraciones entre sí:
Duration primeraParte = Duration.ofMinutes(45);
Duration segundaParte = Duration.ofMinutes(30);
// Sumar duraciones
Duration total = primeraParte.plus(segundaParte); // 1 hora y 15 minutos
// Multiplicar una duración
Duration doble = primeraParte.multipliedBy(2); // 1 hora y 30 minutos
// Dividir una duración
Duration mitad = primeraParte.dividedBy(2); // 22 minutos y 30 segundos
System.out.println("Duración total: " + total);
System.out.println("Duración doble: " + doble);
System.out.println("Duración mitad: " + mitad);
Ajustes temporales con TemporalAdjusters
Aunque los ajustadores temporales (TemporalAdjusters
) son más comunes con fechas, también podemos crear ajustadores personalizados para LocalTime
:
// Crear un ajustador que redondee al cuarto de hora más cercano
TemporalAdjuster redondearCuartoHora = temporal -> {
LocalTime time = LocalTime.from(temporal);
int minutes = time.getMinute();
int mod = minutes % 15;
if (mod < 8) { // Redondear hacia abajo
return time.minusMinutes(mod);
} else { // Redondear hacia arriba
return time.plusMinutes(15 - mod);
}
};
LocalTime ahora = LocalTime.of(14, 23);
LocalTime redondeado = ahora.with(redondearCuartoHora); // 14:30
System.out.println("Hora original: " + ahora);
System.out.println("Redondeado al cuarto de hora: " + redondeado);
Ejemplo práctico: Planificador de citas
Veamos un ejemplo práctico de cómo utilizar estas operaciones para implementar un sencillo planificador de citas:
public class PlanificadorCitas {
private LocalTime inicioJornada;
private LocalTime finJornada;
private Duration duracionCita;
private List<LocalTime> citasReservadas;
public PlanificadorCitas(LocalTime inicio, LocalTime fin, Duration duracionCita) {
this.inicioJornada = inicio;
this.finJornada = fin;
this.duracionCita = duracionCita;
this.citasReservadas = new ArrayList<>();
}
public List<LocalTime> obtenerHorariosDisponibles() {
List<LocalTime> disponibles = new ArrayList<>();
LocalTime horaActual = inicioJornada;
while (horaActual.plus(duracionCita).isBefore(finJornada) ||
horaActual.plus(duracionCita).equals(finJornada)) {
if (estaDisponible(horaActual)) {
disponibles.add(horaActual);
}
horaActual = horaActual.plusMinutes(30); // Intervalos de 30 minutos
}
return disponibles;
}
private boolean estaDisponible(LocalTime hora) {
for (LocalTime citaReservada : citasReservadas) {
LocalTime finCitaReservada = citaReservada.plus(duracionCita);
// Verificar si hay solapamiento
if (!(hora.isAfter(finCitaReservada) ||
hora.plus(duracionCita).isBefore(citaReservada) ||
hora.plus(duracionCita).equals(citaReservada))) {
return false;
}
}
return true;
}
public boolean reservarCita(LocalTime hora) {
if (estaDisponible(hora)) {
citasReservadas.add(hora);
return true;
}
return false;
}
public static void main(String[] args) {
// Crear un planificador para una jornada de 9:00 a 17:00 con citas de 1 hora
PlanificadorCitas planificador = new PlanificadorCitas(
LocalTime.of(9, 0),
LocalTime.of(17, 0),
Duration.ofHours(1)
);
// Reservar algunas citas
planificador.reservarCita(LocalTime.of(10, 0));
planificador.reservarCita(LocalTime.of(14, 0));
// Obtener horarios disponibles
List<LocalTime> disponibles = planificador.obtenerHorariosDisponibles();
System.out.println("Horarios disponibles:");
for (LocalTime hora : disponibles) {
System.out.println(hora);
}
}
}
Este ejemplo muestra cómo podemos utilizar las operaciones de LocalTime
junto con Duration
para implementar un sistema que calcula los horarios disponibles para citas, teniendo en cuenta la duración de cada cita y evitando solapamientos.
Formateo e integración con otras clases de tiempo (Duration)
El manejo efectivo del tiempo en aplicaciones Java no solo implica realizar cálculos y comparaciones, sino también presentar la información temporal de manera adecuada y combinar LocalTime
con otras clases del paquete java.time
. En esta sección exploraremos cómo formatear objetos LocalTime
para su visualización y cómo integrarlos con la clase Duration
para operaciones más complejas.
Formateo de LocalTime
La clase DateTimeFormatter
es la herramienta principal para convertir objetos temporales en cadenas de texto con el formato deseado. Ofrece gran flexibilidad para personalizar la representación de horas según las necesidades específicas de cada aplicación.
Formateadores predefinidos
Java proporciona varios formateadores estándar que podemos utilizar directamente:
LocalTime ahora = LocalTime.of(14, 30, 45);
// Formatos ISO predefinidos
String formatoISO = ahora.format(DateTimeFormatter.ISO_LOCAL_TIME); // "14:30:45"
String formatoBasico = ahora.format(DateTimeFormatter.ISO_TIME); // "14:30:45"
System.out.println("Formato ISO: " + formatoISO);
System.out.println("Formato ISO básico: " + formatoBasico);
Patrones de formato personalizados
Para casos más específicos, podemos crear formateadores con patrones personalizados:
LocalTime tiempo = LocalTime.of(18, 45, 30, 123456789);
// Crear formateadores con patrones personalizados
DateTimeFormatter formato12h = DateTimeFormatter.ofPattern("hh:mm:ss a"); // Formato 12 horas con AM/PM
DateTimeFormatter formatoCorto = DateTimeFormatter.ofPattern("HH:mm"); // Solo hora y minutos
DateTimeFormatter formatoDetallado = DateTimeFormatter.ofPattern("HH:mm:ss.SSS"); // Con milisegundos
// Aplicar los formateadores
String tiempo12h = tiempo.format(formato12h); // "06:45:30 PM"
String tiempoCorto = tiempo.format(formatoCorto); // "18:45"
String tiempoDetallado = tiempo.format(formatoDetallado); // "18:45:30.123"
System.out.println("Formato 12 horas: " + tiempo12h);
System.out.println("Formato corto: " + tiempoCorto);
System.out.println("Formato con milisegundos: " + tiempoDetallado);
Los patrones de formato más comunes para LocalTime
incluyen:
HH
- Hora en formato 24 horas (00-23)hh
- Hora en formato 12 horas (01-12)mm
- Minutos (00-59)ss
- Segundos (00-59)a
- Marcador AM/PMSSS
- Milisegundos (000-999)n
- Nanosegundos
Formateadores con configuración regional (Locale)
Para adaptar el formato a diferentes idiomas y convenciones regionales:
LocalTime medioDia = LocalTime.of(12, 0);
// Formateadores con diferentes configuraciones regionales
DateTimeFormatter formateadorES = DateTimeFormatter.ofPattern("hh:mm a")
.withLocale(new Locale("es", "ES"));
DateTimeFormatter formateadorUS = DateTimeFormatter.ofPattern("hh:mm a")
.withLocale(Locale.US);
DateTimeFormatter formateadorFR = DateTimeFormatter.ofPattern("HH'h'mm")
.withLocale(Locale.FRANCE);
String horaES = medioDia.format(formateadorES); // "12:00 p. m." (puede variar según la JVM)
String horaUS = medioDia.format(formateadorUS); // "12:00 PM"
String horaFR = medioDia.format(formateadorFR); // "12h00"
System.out.println("Formato español: " + horaES);
System.out.println("Formato estadounidense: " + horaUS);
System.out.println("Formato francés: " + horaFR);
Integración con Duration
La clase Duration
representa una cantidad de tiempo en términos de segundos y nanosegundos, y es ideal para trabajar con intervalos de tiempo. Aunque ya vimos algunas operaciones básicas con Duration
en la sección anterior, ahora profundizaremos en su integración con LocalTime
.
Creación de objetos Duration
Existen varias formas de crear objetos Duration
:
// Crear Duration directamente
Duration unaHora = Duration.ofHours(1);
Duration dosMinutos = Duration.ofMinutes(2);
Duration tresSegundos = Duration.ofSeconds(3);
Duration milisegundos = Duration.ofMillis(500);
Duration nanosegundos = Duration.ofNanos(1_000_000);
// Crear Duration combinando unidades
Duration compleja = Duration.ofHours(2)
.plusMinutes(30)
.plusSeconds(15);
// Crear Duration entre dos instantes temporales
LocalTime inicio = LocalTime.of(9, 0);
LocalTime fin = LocalTime.of(10, 30);
Duration duracionClase = Duration.between(inicio, fin); // 1 hora y 30 minutos
System.out.println("Duración de clase: " + duracionClase);
Formateo personalizado de Duration
A diferencia de LocalTime
, la clase Duration
no tiene un método format()
directo. Para presentar una duración de manera legible, podemos implementar nuestras propias soluciones:
Duration duracion = Duration.ofHours(2).plusMinutes(45).plusSeconds(10);
// Método 1: Extraer componentes manualmente
long horas = duracion.toHours();
int minutos = duracion.toMinutesPart();
int segundos = duracion.toSecondsPart();
String formatoManual = String.format("%d:%02d:%02d", horas, minutos, segundos); // "2:45:10"
// Método 2: Usar LocalTime para formatear (si la duración es menor a 24 horas)
LocalTime tiempoDuracion = LocalTime.of(0, 0).plus(duracion);
String formatoConLocalTime = tiempoDuracion.format(DateTimeFormatter.ofPattern("HH:mm:ss")); // "02:45:10"
System.out.println("Duración formateada manualmente: " + formatoManual);
System.out.println("Duración formateada con LocalTime: " + formatoConLocalTime);
Para duraciones que pueden exceder las 24 horas, necesitamos un enfoque diferente:
public static String formatearDuracion(Duration duracion) {
long dias = duracion.toDays();
long horas = duracion.toHoursPart();
int minutos = duracion.toMinutesPart();
int segundos = duracion.toSecondsPart();
StringBuilder sb = new StringBuilder();
if (dias > 0) {
sb.append(dias).append("d ");
}
if (horas > 0 || dias > 0) {
sb.append(horas).append("h ");
}
if (minutos > 0 || horas > 0 || dias > 0) {
sb.append(minutos).append("m ");
}
sb.append(segundos).append("s");
return sb.toString();
}
// Ejemplo de uso
Duration larga = Duration.ofDays(2).plusHours(5).plusMinutes(30).plusSeconds(15);
System.out.println("Duración larga: " + formatearDuracion(larga)); // "2d 5h 30m 15s"
Conversión entre Duration y LocalTime
Podemos utilizar Duration
para manipular objetos LocalTime
y viceversa:
// Convertir LocalTime a Duration (desde medianoche)
LocalTime horaTrabajo = LocalTime.of(8, 30);
Duration desdeMedianoche = Duration.between(LocalTime.MIDNIGHT, horaTrabajo); // 8 horas y 30 minutos
// Aplicar una Duration a un LocalTime
LocalTime inicio = LocalTime.of(9, 0);
Duration duracionReunion = Duration.ofMinutes(45);
LocalTime finReunion = inicio.plus(duracionReunion); // 9:45
System.out.println("Duración desde medianoche: " + desdeMedianoche);
System.out.println("Hora de inicio: " + inicio);
System.out.println("Duración de la reunión: " + duracionReunion);
System.out.println("Hora de finalización: " + finReunion);
Ejemplo práctico: Temporizador de intervalos
Un caso de uso común que combina LocalTime
y Duration
es un temporizador para entrenamientos por intervalos:
public class TemporizadorIntervalos {
private Duration duracionActividad;
private Duration duracionDescanso;
private int repeticiones;
public TemporizadorIntervalos(Duration actividad, Duration descanso, int repeticiones) {
this.duracionActividad = actividad;
this.duracionDescanso = descanso;
this.repeticiones = repeticiones;
}
public void mostrarPlanEntrenamiento() {
LocalTime horaActual = LocalTime.now();
System.out.println("Plan de entrenamiento a partir de: " +
horaActual.format(DateTimeFormatter.ofPattern("HH:mm:ss")));
Duration duracionTotal = Duration.ZERO;
for (int i = 1; i <= repeticiones; i++) {
// Calcular hora de inicio y fin de la actividad
LocalTime inicioActividad = horaActual.plus(duracionTotal);
duracionTotal = duracionTotal.plus(duracionActividad);
LocalTime finActividad = horaActual.plus(duracionTotal);
System.out.printf("Intervalo %d - Actividad: %s a %s (%s)%n",
i,
inicioActividad.format(DateTimeFormatter.ofPattern("HH:mm:ss")),
finActividad.format(DateTimeFormatter.ofPattern("HH:mm:ss")),
formatearDuracion(duracionActividad));
// Si no es la última repetición, añadir descanso
if (i < repeticiones) {
LocalTime inicioDescanso = finActividad;
duracionTotal = duracionTotal.plus(duracionDescanso);
LocalTime finDescanso = horaActual.plus(duracionTotal);
System.out.printf(" - Descanso: %s a %s (%s)%n",
inicioDescanso.format(DateTimeFormatter.ofPattern("HH:mm:ss")),
finDescanso.format(DateTimeFormatter.ofPattern("HH:mm:ss")),
formatearDuracion(duracionDescanso));
}
}
// Mostrar duración total del entrenamiento
System.out.println("\nDuración total del entrenamiento: " + formatearDuracion(duracionTotal));
System.out.println("Hora estimada de finalización: " +
horaActual.plus(duracionTotal).format(DateTimeFormatter.ofPattern("HH:mm:ss")));
}
private String formatearDuracion(Duration duracion) {
long minutos = duracion.toMinutes();
int segundos = duracion.toSecondsPart();
return String.format("%02d:%02d", minutos, segundos);
}
public static void main(String[] args) {
// Crear un temporizador para 4 intervalos de 5 minutos de actividad y 1 minuto de descanso
TemporizadorIntervalos temporizador = new TemporizadorIntervalos(
Duration.ofMinutes(5),
Duration.ofMinutes(1),
4
);
temporizador.mostrarPlanEntrenamiento();
}
}
Este ejemplo muestra cómo podemos combinar LocalTime
y Duration
para crear un planificador de entrenamientos por intervalos, calculando y formateando los tiempos de inicio y fin de cada actividad y descanso.
Integración con otras clases temporales
Además de Duration
, LocalTime
puede integrarse con otras clases del paquete java.time
:
Combinación con LocalDate para crear LocalDateTime
LocalDate hoy = LocalDate.now();
LocalTime ahora = LocalTime.now();
// Combinar fecha y hora
LocalDateTime fechaHoraActual = LocalDateTime.of(hoy, ahora);
// Alternativa: LocalDateTime fechaHoraActual = ahora.atDate(hoy);
System.out.println("Fecha y hora actual: " + fechaHoraActual);
Uso con Period para cálculos basados en unidades de calendario
Aunque Period
está diseñado principalmente para trabajar con fechas, podemos usarlo en combinación con LocalTime
en ciertos escenarios:
LocalTime horaBase = LocalTime.of(10, 0);
Period unMes = Period.ofMonths(1);
// Simulación: ¿Qué hora será en la misma hora del día dentro de un mes?
LocalDateTime fechaHoraBase = horaBase.atDate(LocalDate.now());
LocalDateTime fechaHoraFutura = fechaHoraBase.plus(unMes);
LocalTime horaFutura = fechaHoraFutura.toLocalTime();
System.out.println("Hora base: " + horaBase);
System.out.println("Misma hora dentro de un mes: " + horaFutura);
// Normalmente serán iguales, a menos que haya cambio de horario de verano
Conversión entre formatos de tiempo
En ocasiones necesitamos convertir entre diferentes representaciones de tiempo:
// Convertir segundos desde medianoche a LocalTime
int segundosDesdeMedianoche = 43200; // 12 horas en segundos
LocalTime medioDia = LocalTime.ofSecondOfDay(segundosDesdeMedianoche);
// Convertir nanosegundos desde medianoche a LocalTime
long nanosDesdeMedianoche = 555_000_000_000L; // 9:15:00 en nanosegundos
LocalTime mañana = LocalTime.ofNanoOfDay(nanosDesdeMedianoche);
// Convertir LocalTime a segundos o nanosegundos desde medianoche
LocalTime tiempo = LocalTime.of(15, 30);
int segundos = tiempo.toSecondOfDay(); // 55800 segundos
long nanos = tiempo.toNanoOfDay(); // 55800000000000 nanosegundos
System.out.println("Mediodía: " + medioDia);
System.out.println("Mañana: " + mañana);
System.out.println("Segundos desde medianoche para 15:30: " + segundos);
Estas conversiones son útiles cuando necesitamos interoperar con sistemas que utilizan representaciones numéricas del tiempo o para realizar cálculos específicos.
Ejercicios de esta lección LocalTime
Evalúa tus conocimientos de esta lección LocalTime con nuestros retos de programación de tipo Test, Puzzle, Código y Proyecto con VSCode, guiados por IA.
Streams: match
Gestión de errores y excepciones
CRUD en Java de modelo Customer sobre un ArrayList
Clases abstractas
Listas
Métodos de la clase String
Streams: reduce()
API java.nio 2
Polimorfismo
Pattern Matching
Streams: flatMap()
Llamada y sobrecarga de funciones
Métodos referenciados
Métodos de la clase String
Representación de Fecha
Operadores lógicos
Inferencia de tipos con var
Tipos de datos
Estructuras de iteración
Streams: forEach()
Objetos
Funciones lambda
Uso de Scanner
Tipos de variables
Streams: collect()
Operadores aritméticos
Arrays y matrices
Clases y objetos
Interfaz funcional Consumer
CRUD en Java de modelo Customer sobre un HashMap
Interfaces
Enumeraciones Enums
API Optional
Interfaz funcional Function
Encapsulación
Interfaces
Uso de API Optional
Representación de Hora
Herencia básica
Clases y objetos
Interfaz funcional Supplier
HashMap
Sobrecarga de métodos
Polimorfismo de tiempo de ejecución
OOP en Java
Sobrecarga de métodos
CRUD de productos en Java
Clases sealed
Creación de Streams
Records
Encapsulación
Streams: min max
Herencia
Métodos avanzados de la clase String
Funciones
Polimorfismo de tiempo de compilación
Reto sintaxis Java
Conjuntos
Estructuras de control
Recursión
Excepciones
Herencia avanzada
Estructuras de selección
Uso de interfaces
Operadores
Variables
HashSet
Objeto Scanner
Streams: filter()
Operaciones de Streams
Interfaz funcional Predicate
Streams: sorted()
Configuración de entorno
Uso de variables
Clases
Streams: distinct()
Streams: count()
ArrayList
Mapas
Datos de referencia
Interfaces funcionales
Métodos básicos de la clase String
Tipos de datos
Clases abstractas
Instalación
Funciones
Excepciones
Estructuras de control
Herencia de clases
La clase Scanner
Generics
Streams: map()
Funciones y encapsulamiento
Todas las lecciones de Java
Accede a todas las lecciones de Java y aprende con ejemplos prácticos de código y ejercicios de programación con IDE web sin instalar nada.
Instalación De Java
Introducción Y Entorno
Configuración De Entorno Java
Introducción Y Entorno
Tipos De Datos
Sintaxis
Variables
Sintaxis
Operadores
Sintaxis
Estructuras De Control
Sintaxis
Funciones
Sintaxis
Recursión
Sintaxis
Arrays Y Matrices
Sintaxis
Excepciones
Programación Orientada A Objetos
Clases Y Objetos
Programación Orientada A Objetos
Encapsulación
Programación Orientada A Objetos
Herencia
Programación Orientada A Objetos
Clases Abstractas
Programación Orientada A Objetos
Interfaces
Programación Orientada A Objetos
Sobrecarga De Métodos
Programación Orientada A Objetos
Polimorfismo
Programación Orientada A Objetos
La Clase Scanner
Programación Orientada A Objetos
Métodos De La Clase String
Programación Orientada A Objetos
Excepciones
Programación Orientada A Objetos
Records
Programación Orientada A Objetos
Pattern Matching
Programación Orientada A Objetos
Inferencia De Tipos Con Var
Programación Orientada A Objetos
Enumeraciones Enums
Programación Orientada A Objetos
Generics
Programación Orientada A Objetos
Clases Sealed
Programación Orientada A Objetos
Listas
Framework Collections
Conjuntos
Framework Collections
Mapas
Framework Collections
Funciones Lambda
Programación Funcional
Interfaz Funcional Consumer
Programación Funcional
Interfaz Funcional Predicate
Programación Funcional
Interfaz Funcional Supplier
Programación Funcional
Interfaz Funcional Function
Programación Funcional
Métodos Referenciados
Programación Funcional
Creación De Streams
Programación Funcional
Operaciones Intermedias Con Streams: Map()
Programación Funcional
Operaciones Intermedias Con Streams: Filter()
Programación Funcional
Operaciones Intermedias Con Streams: Distinct()
Programación Funcional
Operaciones Finales Con Streams: Collect()
Programación Funcional
Operaciones Finales Con Streams: Min Max
Programación Funcional
Operaciones Intermedias Con Streams: Flatmap()
Programación Funcional
Operaciones Intermedias Con Streams: Sorted()
Programación Funcional
Operaciones Finales Con Streams: Reduce()
Programación Funcional
Operaciones Finales Con Streams: Foreach()
Programación Funcional
Operaciones Finales Con Streams: Count()
Programación Funcional
Operaciones Finales Con Streams: Match
Programación Funcional
Api Optional
Programación Funcional
Transformación
Programación Funcional
Reducción Y Acumulación
Programación Funcional
Mapeo
Programación Funcional
Streams Paralelos
Programación Funcional
Agrupación Y Partición
Programación Funcional
Filtrado Y Búsqueda
Programación Funcional
Api Java.nio 2
Entrada Y Salida Io
Fundamentos De Io
Entrada Y Salida Io
Leer Y Escribir Archivos
Entrada Y Salida Io
Httpclient Moderno
Entrada Y Salida Io
Clases De Nio2
Entrada Y Salida Io
Api Java.time
Api Java.time
Localtime
Api Java.time
Localdatetime
Api Java.time
Localdate
Api Java.time
Executorservice
Concurrencia
Virtual Threads (Project Loom)
Concurrencia
Future Y Completablefuture
Concurrencia
Spring Framework
Frameworks Para Java
Micronaut
Frameworks Para Java
Maven
Frameworks Para Java
Gradle
Frameworks Para Java
Lombok Para Java
Frameworks Para Java
Quarkus
Frameworks Para Java
Ecosistema Jakarta Ee De Java
Frameworks Para Java
Introducción A Junit 5
Testing
Certificados de superación de Java
Supera todos los ejercicios de programación del curso de Java y obtén certificados de superación para mejorar tu currículum y tu empleabilidad.
En esta lección
Objetivos de aprendizaje de esta lección
- Comprender la creación y manipulación básica de objetos LocalTime.
- Realizar operaciones aritméticas y comparaciones entre instantes de tiempo.
- Formatear LocalTime y combinarlo con otras clases temporales como Duration.
- Implementar ejemplos prácticos de control de horarios y planificación de citas.
- Gestionar conversiones y ajustes temporales con LocalTime y Duration.