HOWTO · Java

Solucione java.text.ParseException: error de fecha no analizable en Java

Este tutorial demuestra java.text.ParseException: error de fecha no analizable en Java.

En esta página

Esta guía explica cómo diagnosticar java.text.ParseException: Unparseable date cuando una cadena de fecha de Java no coincide con su patrón de análisis. Compara la entrada con el patrón de izquierda a derecha y, antes de dar formato al valor analizado, ten en cuenta el texto localizado y las zonas horarias.

Corregir el error java.text.ParseException: Unparseable date en Java

SimpleDateFormat analiza el texto según las letras del patrón; no adivina el formato de fecha previsto. Un fallo de análisis suele indicar que el patrón espera campos o texto distintos de los que contiene la entrada. Por ejemplo, Tue Aug 16 12:30:10 IST 2022 empieza con el día de la semana, seguido del nombre del mes en inglés, el día, la hora, una abreviatura de zona horaria y el año. Un patrón como MMM d, yyyy HH:mm:ss espera una puntuación distinta y omite el día de la semana y la zona, así que no puede procesar esa cadena tal como está escrita.

Revisa toda la entrada, incluidos los separadores y los espacios. Comprueba el día de la semana, el texto del mes, el día, los campos de hora, la zona y el año. Una ParseException indica la posición donde se detuvo el análisis; compara el texto en ese punto con el siguiente campo que exige el patrón. No atribuyas esta excepción por sí sola a una diferencia de zona horaria: por lo general, la zona afecta al instante representado o a cómo se muestra.

Hacer coincidir el patrón de fecha con la cadena de entrada

Las letras del patrón distinguen entre mayúsculas y minúsculas. MM representa el mes, mientras que mm representa los minutos. Usa yyyy para el año calendario; YYYY, en mayúsculas, representa el año basado en semanas y puede dar resultados inesperados cerca del cambio de año. La cantidad y el orden de los campos también deben coincidir con la entrada. Para el texto de fecha proporcionado, el patrón debe incluir el día de la semana (EEE), el mes abreviado (MMM), el día con dos dígitos (dd), la hora en formato de 24 horas (HH:mm:ss), la zona (z) y el año (yyyy).

Para diagnosticar el problema, coloca la entrada y el patrón uno junto al otro y haz coincidir cada elemento en orden. Si el texto contiene campos numéricos para el mes y el día, usa un patrón numérico con el mismo orden y los mismos separadores. Si contiene el nombre del mes, usa un patrón de mes en texto. No «corrijas» el patrón cambiando las mayúsculas de un campo sin comprobar qué significa esa letra.

Configurar deliberadamente la configuración regional y la zona horaria del análisis

Los nombres textuales de meses y días de la semana dependen de la configuración regional. Si la entrada contiene nombres en inglés, pasa Locale.ENGLISH en lugar de depender de la configuración regional predeterminada de la máquina. Esta puede variar entre los equipos de desarrollo y los servidores. Usa la configuración regional con la que se generó el texto y especifícala para que el analizador espere el mismo vocabulario para los meses y los días de la semana.

Una cadena de fecha que incluye una zona contiene información necesaria para interpretar la hora. Las abreviaturas de zonas horarias, como IST, pueden ser ambiguas según la región y la fuente de datos. Si controlas los formatos, prefiere un desplazamiento numérico inequívoco o un identificador de zona basado en una región. Al analizar texto existente, confirma con quien lo generó qué significa la abreviatura. Al dar formato, establece explícitamente una zona horaria para que la hora mostrada no dependa silenciosamente de la máquina anfitriona. Esto afecta a la interpretación o a la visualización; no corrige campos de fecha que no coinciden.

Ejecutar un ejemplo completo de análisis y formato de salida

Con el patrón que no coincide MMM d, yyyy HH:mm:ss, el análisis de la entrada proporcionada mediante new SimpleDateFormat("MMM d, yyyy HH:mm:ss", Locale.ENGLISH).parse(input) falla porque el patrón espera un nombre de mes al principio, mientras que la entrada empieza con el día de la semana. La excepción resultante es java.text.ParseException: Unparseable date: "Tue Aug 16 12:30:10 IST 2022". El patrón corregido que aparece a continuación tiene en cuenta el día de la semana, el mes, el día, la hora, la zona y el año. Usa una configuración regional inglesa y da formato al instante analizado en UTC. Para que el resultado mostrado sea determinista, este ejemplo usa UTC en la entrada en lugar de la abreviatura ambigua IST indicada antes. En el código de una aplicación, prefiere una representación inequívoca de la zona cuando controles el formato de entrada.

Ejecuta este ejemplo:

El código y las etiquetas o salidas visibles de esta sección se mantienen en inglés.

import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;

public class ParseDateExample {
    public static void main(String[] args) {
        String input = "Tue Aug 16 10:30:10 UTC 2022";
        SimpleDateFormat parser = new SimpleDateFormat(
                "EEE MMM dd HH:mm:ss z yyyy", Locale.ENGLISH);
        ParsePosition position = new ParsePosition(0);
        Date parsed = parser.parse(input, position);
        if (parsed == null || position.getIndex() != input.length()) {
            System.out.println("Input did not match the pattern.");
            return;
        }

        SimpleDateFormat display = new SimpleDateFormat(
                "EEE MMM d, yyyy HH:mm:ss 'UTC'", Locale.ENGLISH);
        display.setTimeZone(TimeZone.getTimeZone("UTC"));
        System.out.println(display.format(parsed));
    }
}
Tue Aug 16, 2022 10:30:10 UTC

El analizador lee el texto de origen, mientras que el segundo formateador elige un formato de salida legible y una zona de visualización explícita.