Join FlipAndroid.COM Telegram Group: https://t.me/joinchat/F_aqThGkhwcLzmI49vKAiw


Java.text.ParseException: fecha inquebrantable

Tengo el siguiente error: 'java.text.ParseException: Unparseable fecha: "Aug 31 09:53:19 2011"' con este formato: new SimpleDateFormat("MMM dd HH:mm:ss yyyy");

¿Alguien ve el problema?

  • Comprueba si la aplicación está disponible en Android Market
  • SCAN_RESULTS_AVAILABLE_ACTION devolver la lista vacía en Android 6.0
  • ¿Qué es MergeRootFrame en FrameLayout?
  • Android: pestañas sin barra de acción
  • Cómo comprimir mp4 video con MediaCodec Android?
  • Android crea un "botón plano"
  • Cómo obtener el código de estado en la respuesta correcta Volley Android
  • Escuchando la notificación en Android
  • ¿Las geofencias de Android sobreviven a un reinicio?
  • ¿Cómo hacer algo cuando una casilla de verificación cambia de estado?
  • RequestCode incorrecto en onActivityResult
  • Cómo crear un grupo RadioButton en la ventana preference.xml?
  • 3 Solutions collect form web for “Java.text.ParseException: fecha inquebrantable”

    Asegúrese de que está utilizando la configuración regional correcta. (El SimpleDateFormat(String) utiliza la configuración regional predeterminada del sistema , que puede no ser la que desea usar.)

    Esto funciona bien en mi máquina:

     String input = "Aug 31 09:53:19 2011"; DateFormat df = new SimpleDateFormat("MMM dd HH:mm:ss yyyy", Locale.US); System.out.println(df.parseObject(input)); 

    (Mientras utiliza Locale.FRENCH por ejemplo, los resultados en un ParseException .)

    El formato en sí está bien para la entrada que dio. Pero es posible que obtenga este error si su configuración regional predeterminada se establece en algo donde "Aug" no es una abreviatura válida de un nombre de mes. Intenta usar, por ejemplo, Locale.US y verás que funcionará:

     DateFormat df = new SimpleDateFormat("MMM dd HH:mm:ss yyyy", Locale.US); Date date = df.parse("Aug 31 09:53:19 2011"); 

    Tl dr

     LocalDateTime ldt = LocalDateTime.parse( "Aug 31 09:53:19 2011" , DateTimeFormatter.ofPattern( "MMM dd HH:mm:ss yyyy" ).withLocale( Locale.US ) ) ; 

    Detalles

    Las otras dos respuestas de aioobe y Jesper son correctas: Implícitamente usando una Locale con un lenguaje humano que no coincide con el idioma de su texto de entrada.

    Esta respuesta explica una nueva forma de hacer el trabajo. Además, las otras respuestas no abordan la cuestión crucial de la zona horaria.

    Java.time

    Avance rápido unos años más tarde de esta publicación, y ahora tenemos el nuevo paquete java.time integrado en Java 8 y versiones posteriores. Estas nuevas clases suplantan las antiguas clases java.util.Date/.Calendar & SimpleDateFormat. Esas viejas clases han demostrado ser problemáticas, confusas y defectuosas.

    Patrón del formateador

    Defina los datos a analizar y su formato.

     String input = "Aug 31 09:53:19 2011"; DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "MMM dd HH:mm:ss uuuu" ); 

    Si no se especifica, DateTimeFormatter se asigna a la configuración Locale que es actualmente la predeterminada en la JVM. Este valor predeterminado puede cambiar en cualquier momento, incluso durante el tiempo de ejecución (!). Por lo tanto, siempre especifique la configuración Locale deseada / esperada.

     formatter = formatter.withLocale( Locale.US ); // Or Locale.UK, Locale.CANADA_FRENCH, etc. 

    Dado que la entrada carece de cualquier zona horaria o offset-from- UTC información, analizar como LocalDateTime .

     LocalDateTime ldt = LocalDateTime.parse( input , formatter ); 

    Si desde el contexto conoce el offset deseado desde UTC o una zona horaria para este valor de fecha y hora, asígelo.

    Si UTC, utilice la constante ZoneOffset.UTC para obtener un objeto OffsetDateTime .

     OffsetDateTime odt = ldt.atOffset( ZoneOffset.UTC ); 

    Una zona horaria es una compensación de UTC más un conjunto de reglas para manejar anomalías tales como horario de verano (DST). Utilice nombres apropiados de zona horaria , nunca las abreviaturas de 3-4 letras .

     ZoneId zoneId_Montreal = ZoneId.of( "America/Montreal" ); ZonedDateTime zdt = ldt.atZone( zoneId_Montreal ); 

    Especificar zona horaria

    Este elemento del lenguaje humano fue la pieza clave que faltaba para responder a la Cuestión. Especificar la configuración Locale correcta para el lenguaje humano que coincida con el idioma de la cadena de entrada resuelve ese problema.

    Pero tenga en cuenta que la zona horaria también es crítica; Las otras respuestas ignoraron este problema implicando implícitamente la zona horaria predeterminada actual de la JVM. Esto no es recomendable, ya que depende del sistema operativo anfitrión como un valor inicial predeterminado (por lo que puede variar) y además cualquier código en cualquier subproceso de cualquier aplicación dentro de la JVM puede cambiar la zona horaria predeterminada actual de JVM durante el tiempo de ejecución. Es mejor especificar la zona horaria deseada / esperada que confiar implícitamente en el default.

    Objetos inmutables

    Tenga en cuenta la sintaxis. Estas clases están diseñadas para ser inmutables . Así que en lugar de modificar (mutar) un objeto, se crea un nuevo objeto nuevo basado en los valores del objeto antiguo. Esto significa que no estamos afectando el objeto DateTimeFormatter definido anteriormente y mantenido en la variable formatter (referencia de objeto). Estamos creando, usando y descartando un nuevo objeto DateTimeFormatter (en realidad, dos nuevos objetos) dentro de esta línea de código.

    Referencia del método

    La documentación sugiere que una forma alternativa de analizar una cadena es llamar al método parse en el que pasa una referencia de método (nueva en Java 8) a la clase del tipo de resultado que desea (como TemporalQuery ): ZonedDateTime::from , LocalDateTime::from , LocalDate::from , y así sucesivamente.

     ZonedDateTime zdt = formatter.withZone( zoneId_Montreal ).withLocale( Locale.ENGLISH ).parse( input, ZonedDateTime :: from ); 

    Para la demostración, vamos a dar la vuelta y crear una representación de la cadena de ese valor ZonedDateTime , pero en francés québécois.

     String output = formatter.withLocale( Locale.CANADA_FRENCH ).format( zdt ); 

    Incluso mejor, vamos a localizar en lugar de codificar un formato determinado.

     String outputLocalized = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.FULL ).withLocale( Locale.CANADA_FRENCH ).format( zdt ); 

    Descarga en la consola.

     System.out.println( "input: " + input ); System.out.println( "formatter: " + formatter ); System.out.println( "zdt: " + zdt ); System.out.println( "output: " + output ); System.out.println( "outputLocalized: " + outputLocalized ); 

    Cuando se ejecuta.

     input: Aug 31 09:53:19 2011 formatter: Text(MonthOfYear,SHORT)' 'Value(DayOfMonth,2)' 'Value(HourOfDay,2)':'Value(MinuteOfHour,2)':'Value(SecondOfMinute,2)' 'Value(YearOfEra,4,19,EXCEEDS_PAD) zdt: 2011-08-31T09:53:19-04:00[America/Montreal] output: août 31 09:53:19 2011 outputLocalized: mercredi 31 août 2011 9 h 53 EDT 

    Acerca de java.time

    El framework java.time está integrado en Java 8 y posterior. Estas clases suplantan las viejas clases problemáticas de fecha y hora, como java.util.Date , .Calendar , y java.text.SimpleDateFormat .

    El proyecto Joda-Time , ahora en modo de mantenimiento , recomienda la migración a java.time.

    Para obtener más información, consulte el Tutorial de Oracle . Y busca Stack Overflow para muchos ejemplos y explicaciones.

    Gran parte de la funcionalidad de java.time se retroporta a Java 6 y 7 en ThreeTen-Backport y se adapta más a Android en ThreeTenABP .

    El proyecto ThreeTen-Extra extiende java.time con clases adicionales. Este proyecto es un terreno probatorio para posibles adiciones futuras a java.time.

    FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.