Java Fecha y Hora

⚡ Resumen inteligente

Java El manejo de fechas y horas combina las clases heredadas java.util.Date y SimpleDateFormat con la API moderna java.time introducida en Java 8, que proporciona a los desarrolladores tipos inmutables y seguros para subprocesos para un trabajo preciso con el calendario.

  • 🕒 Fecha de legado: La clase java.util.Date almacena un instante en milisegundos e imprime una cadena predeterminada mediante el método toString.
  • 🔤 Letras de patrones: SimpleDateFormat utiliza letras como yyyy, MM, dd, HH, mm, ss y zzz para definir formatos de salida personalizados.
  • 🇧🇷 Comparación: El método compareTo devuelve un número entero negativo, cero o positivo para ordenar cronológicamente dos instancias de Date.
  • 🆕 API moderna: En java.time, LocalDate, LocalDateTime, ZonedDateTime e Instant reemplazan Date y Calendar con objetos inmutables.
  • 🧵 Seguridad del hilo: DateTimeFormatter es inmutable y seguro para compartir, mientras que SimpleDateFormat necesita sincronización o un contenedor ThreadLocal.
  • 🔁 Interoperabilidad: Convierta entre las API antiguas y nuevas utilizando las funciones auxiliares Date.toInstant, Date.from y Calendar.toInstant.

Java Fecha y Hora

Manejo de fechas y horas en Java Es una parte rutinaria de la creación de lógica de programación, marcas de tiempo de registro, informes y registros de auditoría. Antes de escribir cualquier código, es útil conocer los parámetros que componen una fecha:

  • El year (en dos o cuatro dígitos).
  • El mes (como dos dígitos, como las tres primeras letras del mes o como el nombre completo del mes).
  • El datos (el número real del día del mes).
  • El day (el nombre del día en la fecha indicada, como dom., lun., mar.).

Java Expone muchos otros parámetros que describen un momento en la línea de tiempo, como la era, la semana del año, la zona horaria y el desfase horario. Las secciones siguientes cubren cada uno de ellos con ejemplos prácticos.

Cómo utilizar la fecha en Java

Mostrar fecha en Java

Java proporciona una Date clase en el java.util Paquete. La clase almacena un instante específico en el tiempo con precisión de milisegundos y ofrece métodos auxiliares para imprimir, comparar y formatear ese instante. Para obtener la fecha y hora actuales, instancie la clase con su constructor predeterminado:

import java.util.Date;

class Date_Ex1 {
    public static void main(String args[]) {
        // Instantiate a Date object by invoking its constructor
        Date objDate = new Date();
        // Display the Date and Time using toString()
        System.out.println(objDate.toString());
    }
}

Salida:

Wed Nov 29 06:36:22 UTC 2017

El ejemplo imprime la fecha en el formato toString predeterminado. Para mostrar el mismo instante en un patrón diferente, primero debe comprender las letras de formato que Java usos.

SimpleDateFormat: analizar y formatear fechas

El SimpleDateFormat clase en java.text convierte un Date objeto en una cadena formateada y analiza una cadena formateada de nuevo en una DateUtiliza letras con patrones que se corresponden con un componente de fecha u hora. La siguiente tabla enumera todas las letras compatibles:

CartaComponente de fecha u horaEjemplo
GDesignador de eraAD
yAño 2026
MMes del añojulio o julio o 07
wSemana en el año27
WSemana en mes2
DDía en el año189
dDía en mes10
FDía de la semana en el mes2
ENombre del día en la semanamartes o martes
uNúmero de día de la semana (1 = Monday, 7 = Domingo)1
aMarcador AM o PMPM
HHora del día (0-23)0
kHora del día (1-24)24
KHora en AM o PM (0-11)0
hHora en AM o PM (1-12)12
mMinuto en hora30
sSegundo en minuto55
SMilisegundo978
zZona horaria (nombre)Hora estándar del Pacífico; PST; GMT -08: 00
ZZona horaria (desplazamiento RFC 822)-0800
XZona horaria (desplazamiento según la norma ISO 8601)-08 o -0800 o -08:00

No es necesario que recuerdes toda la tabla. Consúltala siempre que crees un nuevo patrón.

Cómo usar SimpleDateFormat

SimpleDateFormat es una subclase de DateFormat Esto te permite formatear y analizar fechas usando las letras del patrón anterior. Combina las letras para describir la cadena exacta que deseas generar o leer.

Por ejemplo:

  1. Formato de fecha requerido: 2012.10.23 20:20:45 PST. El patrón de formato apropiado es yyyy.MM.dd HH:mm:ss zzz.
  2. Formato de fecha requerido: 09:30:00 AM 23-May-2012. El patrón de formato apropiado es hh:mm:ss a dd-MMM-yyyy.

Tip: Mayúsculas M es mes, minúscula m es minúsculo. Mayúscula H es un reloj de 24 horas, minúsculas h Es un reloj de 12 horas. Mezclarlos produce un resultado erróneo silencioso.

El siguiente programa imprime la fecha actual dos veces, una en formato predeterminado y otra mediante un patrón SimpleDateFormat:

import java.text.SimpleDateFormat;
import java.util.Date;

class TestDates_Format {
    public static void main(String args[]) {
        // Current system date and time is assigned to objDate
        Date objDate = new Date();
        System.out.println(objDate);

        // Build the target pattern and format the date
        String strDateFormat = "hh:mm:ss a dd-MMM-yyyy";
        SimpleDateFormat objSDF = new SimpleDateFormat(strDateFormat);
        System.out.println(objSDF.format(objDate));
    }
}

Salida:

Wed Nov 29 06:31:41 UTC 2017
06:31:41 AM 29-Nov-2017

Ejemplo de comparación de fechas

Ejemplo de comparación de fechas

La forma más fiable de pedir dos Date los objetos son el compareTo() Método. Devuelve un entero negativo cuando la llamada se realiza antes, cero cuando ambos instantes coinciden y un entero positivo cuando la llamada se realiza después. El siguiente fragmento analiza dos cadenas de fecha e imprime su orden relativo:

import java.text.SimpleDateFormat;
import java.text.ParseException;
import java.util.Date;

class TestDates_Compare {
    public static void main(String args[]) throws ParseException {

        SimpleDateFormat objSDF = new SimpleDateFormat("dd-MM-yyyy");
        Date dt_1 = objSDF.parse("20-08-1981");
        Date dt_2 = objSDF.parse("12-10-2012");

        System.out.println("Date1 : " + objSDF.format(dt_1));
        System.out.println("Date2 : " + objSDF.format(dt_2));

        // compareTo returns > 0 when dt_1 is after dt_2
        if (dt_1.compareTo(dt_2) > 0) {
            System.out.println("Date 1 occurs after Date 2");
        }
        // compareTo returns < 0 when dt_1 is before dt_2
        else if (dt_1.compareTo(dt_2) < 0) {
            System.out.println("Date 1 occurs before Date 2");
        }
        // compareTo returns 0 when both dates are equal
        else {
            System.out.println("Both are the same date");
        }
    }
}

Salida:

Date1 : 20-08-1981
Date2 : 12-10-2012
Date 1 occurs before Date 2

Nota: El código original utilizaba el patrón dd-mm-yyyy. La minúscula mm La letra es minuto, no mes, por lo que el analizador produjo silenciosamente un valor de mes incorrecto. La solución anterior utiliza mayúsculas. MM para el mes, que es la letra del patrón correcto.

Java 8 API moderna de fecha y hora (java.time)

Java 8 introdujo el java.time Paquete con una API rediseñada inspirada en la biblioteca Joda-Time. Las nuevas clases son inmutables, seguras para subprocesos y separan el calendario humano de la línea de tiempo de la máquina. Los tipos más comunes son:

  • LocalDate para una fecha sin hora ni zona horaria (por ejemplo, un cumpleaños).
  • LocalTime para una hora en el reloj de pared sin fecha ni zona horaria.
  • LocalDateTime para una fecha y hora sin zona horaria.
  • ZonedDateTime para una fecha y hora con una zona horaria específica.
  • OffsetDateTime para una fecha y hora con un desplazamiento UTC pero sin zona horaria con nombre.
  • Instant para una marca de tiempo de máquina medida desde la época UNIX.
  • Duration y Period para importes basados ​​en el tiempo y en la fecha.

El siguiente ejemplo imprime la fecha, la hora, la marca de tiempo y la zona horaria actuales utilizando la API moderna:

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZonedDateTime;
import java.time.Instant;
import java.time.ZoneId;

class ModernDateDemo {
    public static void main(String args[]) {
        LocalDate today = LocalDate.now();
        LocalDateTime now = LocalDateTime.now();
        ZonedDateTime zoned = ZonedDateTime.now(ZoneId.of("Asia/Kolkata"));
        Instant epoch = Instant.now();

        System.out.println("LocalDate     : " + today);
        System.out.println("LocalDateTime : " + now);
        System.out.println("ZonedDateTime : " + zoned);
        System.out.println("Instant       : " + epoch);
    }
}

Cada tipo tiene métodos de fábrica (now, of, parse) y operaciones inmutables (plusDays, minusHours, withYear) que devuelven un valor nuevo en lugar de modificar el objeto original.

DateTimeFormatter: Formatear fechas en formato moderno Java

DateTimeFormatter in java.time.format reemplaza SimpleDateFormatUtiliza el mismo estilo de letras de patrón, es inmutable y se puede compartir de forma segura entre hilos sin sincronización adicional. La clase también expone constantes predefinidas como ISO_LOCAL_DATE y ISO_ZONED_DATE_TIME para formatos estándar.

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

class FormatterDemo {
    public static void main(String args[]) {
        LocalDateTime now = LocalDateTime.now();

        DateTimeFormatter iso = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
        DateTimeFormatter human = DateTimeFormatter.ofPattern("hh:mm:ss a dd-MMM-yyyy");

        System.out.println(now.format(iso));
        System.out.println(now.format(human));

        LocalDateTime parsed = LocalDateTime.parse("2026-07-04T09:30:00", iso);
        System.out.println("Parsed back : " + parsed);
    }
}

Para comparar dos fechas en la API moderna, llame a isBefore, isAfter, o isEqualEstos métodos se leen con mayor claridad que compareTo y trabajar con cada uno java.time clase.

Seguridad de los hilos y mejores prácticas para Java Fecha y Hora

Ambos java.util.Date y SimpleDateFormat son anteriores a los concurrentes modernos. Javay cada una tiene sus inconvenientes conocidos. Siga las prácticas que se indican a continuación para mantener un manejo correcto de las fechas en el código de producción:

  • Prefiera java.time a Date y Calendar. Los nuevos tipos son inmutables y seguros para subprocesos, y modelan el dominio con mayor precisión (fechas sin horas, horas sin zonas horarias, etc.).
  • No compartas un SimpleDateFormat entre hilos. La clase almacena el estado de análisis interno y no es segura para subprocesos. Envuélvala en una ThreadLocal, sincronizar en la instancia o cambiar a DateTimeFormatter.
  • Especifique siempre una configuración regional. Los nombres de los meses y los días cambian con la configuración regional predeterminada de la JVM, lo que hace que patrones como MMM y EEE no portátil. Pase una configuración regional explícitamente (por ejemplo, Locale.ENGLISH).
  • Sea explícito sobre las zonas horarias. LocalDateTime no tiene zona, así que conviértalo a ZonedDateTime or Instant Siempre que el momento exacto importa, especialmente para los registros, las columnas de la base de datos y las cargas útiles de la red.
  • Realice la conversión entre las dos API con cuidado. Usar date.toInstant(), Date.from(instant), y calendar.toInstant().atZone(zone) en la frontera entre el código heredado y el código moderno.
  • Almacenar marcas de tiempo en UTC. Persiste y transmit fechas como UTC (un Instant o una cadena ISO 8601) y convertir a la zona de usuario solo cuando se muestre.

Preguntas Frecuentes

Llama a LocalDateTime.now() del paquete java.time para obtener una fecha y hora en la zona del sistema, o a LocalDate.now() para obtener solo una fecha. En versiones anteriores Java, utilice new java.util.Date() para obtener el instante actual.

java.util.Date representa un instante en milisegundos desde la época y es mutable. LocalDate modela una fecha de calendario sin hora ni zona horaria, es inmutable y segura para subprocesos, y ofrece métodos más claros como plusDays e isBefore.

No. SimpleDateFormat mantiene un estado de análisis mutable y produce resultados erróneos cuando se comparte entre subprocesos. Envuélvalo en un ThreadLocal, sincronícelo en la instancia o cambie a DateTimeFormatter, que es inmutable y seguro.

Pase la cadena exacta “aaaa-MM-dd”. MM en mayúsculas representa el mes y mm en minúsculas, los minutos. Para la fecha y hora completas, use “aaaa-MM-dd HH:mm:ss”. Especifique siempre la configuración regional para que los nombres de los meses sean reproducibles.

Con Date heredado, use compareTo, que devuelve un entero negativo, cero o positivo. Con java.time, llame a isBefore, isAfter o isEqual en un LocalDate o Instant. Ambos métodos respetan el orden cronológico.

Llama a date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime(). Para volver atrás, usa Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant()). Selecciona la zona explícitamente cuando el momento exacto sea importante.

Los modelos de IA entrenados con corpus de registros y documentos infieren el patrón probable a partir de cadenas de muestra y devuelven un patrón DateTimeFormatter coincidente. Los clasificadores de aprendizaje automático también señalan campos ambiguos, como el orden mes-día frente al día-mes.

Sí. GitHub Copilot sugiere patrones DateTimeFormatter, conversiones ZonedDateTime y JUnit Pruebas para salida sensible a la configuración regional. RevRevisa cada sugerencia para ver las letras del patrón, la configuración regional y la zona horaria correctas antes de confirmar.

Resumir este post con: