Clase Java DateTimeFormatter
DateTimeFormatter es una clase importante en la API de fecha y hora introducida en Java 8 (paquete java.time), utilizada para formatear y analizar objetos de fecha y hora. Esta clase proporciona potentes funciones para manejar la visualización y conversión de fechas y horas.
En pocas palabras, DateTimeFormatter tiene principalmente dos funciones:
- Formatear: convertir objetos de fecha y hora (como LocalDate, LocalDateTime) en cadenas con un formato específico.
- Analizar: convertir cadenas que coinciden con el formato en objetos de fecha y hora.
¿Por qué se necesita DateTimeFormatter?
Antes de Java 8, usábamos SimpleDateFormat para el formateo y análisis de fechas, pero tenía varias desventajas:
- No era seguro para subprocesos.
- Su diseño era bastante anticuado.
- El manejo de errores no era amigable.
DateTimeFormatter resuelve estos problemas:
- Seguridad para subprocesos: se puede compartir la instancia de forma segura en entornos de múltiples subprocesos.
- Inmutable: una vez creado, no se puede modificar.
- Formatos predefinidos más ricos: proporciona una gran cantidad de formatos integrados.
- Mejor manejo de errores: cuando el análisis falla, proporciona mensajes de error más detallados.
Uso básico
Formateadores predefinidos
DateTimeFormatter proporciona muchas constantes de formateo predefinidas:
Ejemplo
// Usando el formateador predefinido
System.out.println(now.format(DateTimeFormatter.ISO_LOCAL_DATE)); // 2023-11-15
System.out.println(now.format(DateTimeFormatter.ISO_LOCAL_TIME)); // 14:30:45.123
System.out.println(now.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME)); // 2023-11-15T14:30:45.123
Patrones personalizados
Puedes crear formateadores personalizados utilizando cadenas de patrón:
Ejemplo
String formattedDateTime = now.format(formatter); // Formatear
System.out.println(formattedDateTime); // 2023-11-15 14:30:45
// Analizar
LocalDateTime parsedDateTime = LocalDateTime.parse("2023-11-15 14:30:45", formatter);
// Formato de fecha chino común
DateTimeFormatter chineseFormatter = DateTimeFormatter.ofPattern(yyyyañoMMmesdddía);
String formattedDate = today.format(chineseFormatter);
System.out.println(Fecha en formato chino: + formattedDate);
// Analizando una cadena de fecha en chino
String chineseDateStr = 2023año05mes20día;
LocalDate parsedDate = LocalDate.parse(chineseDateStr, chineseFormatter);
System.out.println(Fecha analizada: + parsedDate);
// Otros formatos comunes
DateTimeFormatter formatter1 = DateTimeFormatter.ofPattern("yyyy-MM-dd");
DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern("MM/dd/yyyy");
DateTimeFormatter formatter3 = DateTimeFormatter.ofPattern(yyyyañoMMmesdddía EEEE, Locale.CHINA);
System.out.println(Formato 1: + today.format(formatter1));
System.out.println(Formato 2: + today.format(formatter2));
System.out.println(Formato 3 (con día de la semana): + today.format(formatter3));
Formato localizado
Puedes crear formateadores según diferentes regiones:
Ejemplo
DateTimeFormatter.ofLocalizedDate(FormatStyle.LONG)
.withLocale(Locale.FRENCH);
String frenchDate = now.format(frenchFormatter);
System.out.println(frenchDate); // 15 novembre 2023
Explicación de las letras del patrón
Al crear formatos personalizados, debes utilizar letras de patrón específicas:
| Letra | Significado | Ejemplo |
|---|---|---|
| y | año | yyyy → 2023 |
| M | mes | MM → 11 |
| d | día | dd → 15 |
| H | Hora (0-23) | HH → 14 |
| h | Hora (1-12) | hh → 02 |
| m | Minuto | mm → 30 |
| s | segundo | ss → 45 |
| S | Milisegundo | SSS → 123 |
| E | Día de la semana | E → miércoles |
| a | AM/PM | a → tarde |
Mejores prácticas
Reutilizar formateadores
Dado que DateTimeFormatter es seguro para subprocesos, se recomienda definir los formateadores de uso común como constantes:
Ejemplo
public static final DateTimeFormatter STANDARD_FORMATTER =
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
// Forma de uso
String formatted = LocalDateTime.now().format(STANDARD_FORMATTER);
}
Ejemplo completo:
Ejemplo
import java.time.LocalTime;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class EjemploTest {
public static void main(String[] args) {
// 1. Ejemplo de LocalDate
LocalDate currentDate = LocalDate.now();
System.out.println(Fecha actual: + currentDate);
LocalDate specificDate = LocalDate.of(2023, 5, 20);
System.out.println(Fecha específica: + specificDate);
// 2. Ejemplo de LocalTime
LocalTime currentTime = LocalTime.now();
System.out.println(Hora actual: + currentTime);
LocalTime specificTime = LocalTime.of(14, 30, 15);
System.out.println(Hora específica: + specificTime);
// 3. Ejemplo de LocalDateTime
LocalDateTime currentDateTime = LocalDateTime.now();
System.out.println(Fecha y hora actuales: + currentDateTime);
LocalDateTime specificDateTime = LocalDateTime.of(2023, 5, 20, 14, 30, 15);
System.out.println(Fecha y hora específicas: + specificDateTime);
// 4. Ejemplo de DateTimeFormatter
// Formateo básico
DateTimeFormatter basicFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
System.out.println(Formato básico: + currentDate.format(basicFormatter));
// Formateo en chino
DateTimeFormatter chineseFormatter = DateTimeFormatter.ofPattern(yyyyañoMMmesdddía, Locale.CHINA);
System.out.println(Fecha en chino: + currentDate.format(chineseFormatter));
// Formateo en chino con día de la semana
DateTimeFormatter weekFormatter = DateTimeFormatter.ofPattern(yyyyañoMMmesdddía EEEE, Locale.CHINA);
System.out.println(Fecha en chino con día de la semana: + currentDate.format(weekFormatter));
// Formateo de hora
DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern(HHCuandommdividirsssegundo);
System.out.println(Hora en chino: + currentTime.format(timeFormatter));
// Formateo de fecha y hora
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
System.out.println(Fecha y hora estándar: + currentDateTime.format(dateTimeFormatter));
// Analizar fecha
String dateStr = "2023-05-20";
LocalDate parsedDate = LocalDate.parse(dateStr, basicFormatter);
System.out.println(Fecha analizada: + parsedDate);
// Analizar fecha en chino
String chineseDateStr = 2023año05mes20día;
LocalDate parsedChineseDate = LocalDate.parse(chineseDateStr, chineseFormatter);
System.out.println(Fecha en chino analizada: + parsedChineseDate);
}
}
El resultado de la salida es:
当前日期: 2025-05-01 特定日期: 2023-05-20 当前时间: 10:46:38.591747 特定时间: 14:30:15 当前日期时间: 2025-05-01T10:46:38.592002 特定日期时间: 2023-05-20T14:30:15 基本格式化: 2025-05-01 中文日期: 2025年05月01日 带星期的中文日期: 2025年05月01日 星期四 中文时间: 10时46分38秒 标准日期时间: 2025-05-01 10:46:38 解析后的日期: 2023-05-20 解析后的中文日期: 2023-05-20
Manejo de excepciones de análisis
Al analizar cadenas, debes manejar las posibles excepciones:
Ejemplo
LocalDateTime dateTime = LocalDateTime.parse("2023-11-15", formatter);
} catch (DateTimeParseException e) {
System.err.println(No se pudo analizar la fecha y hora: + e.getMessage());
}
Considerar la zona horaria
Si necesitas manejar zonas horarias, puedes usarZonedDateTimey patrones de zona horaria específicos:
Ejemplo
ZonedDateTime zonedDateTime = ZonedDateTime.now(ZoneId.of("Asia/Shanghai"));
System.out.println(zonedDateTime.format(formatter)); // 2023-11-15 14:30:45 CST
Resumen
DateTimeFormatter es una poderosa herramienta para el formateo y análisis en la API de fecha y hora de Java 8. En comparación con el antiguo SimpleDateFormat, es más seguro, flexible y fácil de usar. Dominar el uso de DateTimeFormatter te permite manejar de manera más eficiente diversas necesidades de formatos de fecha y hora.
Recuerda los puntos clave:
- Utiliza formateadores predefinidos para formatos comunes.
- Utiliza ofPattern() para crear formatos personalizados.
- Considera los requisitos de localización y zona horaria.
- Reutiliza instancias de formateadores seguros para subprocesos.
- Maneja correctamente las excepciones de análisis.