Efectos secundarios inesperados al analizar fechas en Android

En varios proyectos de Android, utilizo la siguiente función estática para analizar fechas como 1900-12-31 . Por supuesto, esta función debe ser determinista – pero resulta que no lo es. ¿Por qué?

Normalmente, analiza la fecha 2010-10-30 , por ejemplo, en la instancia de Date correcta que contiene ese valor. Pero he notado que cuando tengo un IntentService funcionando al mismo tiempo y analizando algunas fechas, esta función analiza la misma fecha que arriba a 1983-01-20 , que es una de las fechas analizadas en el IntentService . ¿Cómo puede suceder esto?

 public static Date dateFromString(String dateStr) { SimpleDateFormat mDateFormat = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()); SimpleDateFormat mDateTimeFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ", Locale.getDefault()); Date dateOut = null; try { if (dateStr != null) { if (dateStr.length() == 7) { if (dateStr.startsWith("--")) { dateStr = "0000"+dateStr.substring(1); } } else if (dateStr.length() == 6) { if (dateStr.startsWith("-")) { dateStr = "0000"+dateStr; } } else if (dateStr.length() == 5) { dateStr = "0000-"+dateStr; } else if (dateStr.matches("[0-9]{2}\\.[0-9]{2}\\.[0-9]{4}")) { dateStr = dateStr.substring(6, 10)+"-"+dateStr.substring(3, 5)+"-"+dateStr.substring(0, 2); } else if (dateStr.matches("[0-9]{2}\\/[0-9]{2}\\/[0-9]{4}")) { dateStr = dateStr.substring(6, 10)+"-"+dateStr.substring(3, 5)+"-"+dateStr.substring(0, 2); } else if (dateStr.matches("[0-9]{8}")) { dateStr = dateStr.substring(0, 4)+"-"+dateStr.substring(4, 6)+"-"+dateStr.substring(6, 8); } if (dateStr.length() >= 20) { String dateTimeStr = dateStr.trim(); if (dateTimeStr.endsWith("Z")) { dateTimeStr = dateStr.substring(0, dateTimeStr.length()-1)+"+0000"; } if (dateStr.charAt(10) == ' ') { dateTimeStr = dateStr.substring(0, 10)+"T"+dateStr.substring(11); } try { dateOut = mDateTimeFormat.parse(dateTimeStr); } catch (Exception e2) { dateOut = mDateFormat.parse(dateStr); } } else { dateOut = mDateFormat.parse(dateStr); } } } catch (Exception e) { dateOut = null; } return dateOut; } 

Edit: Hago el análisis en el onCreate() mi Activity onCreate() donde comienzo un AsyncTask que hace el trabajo. En onStop() la onStop() , se inicia un servicio de fondo que realiza el mismo trabajo. Cuando cierro la aplicación (onStop ()) y lo reinicio rápidamente (onCreate ()), ambos parecen estar ejecutándose simultáneamente y el error ocurre.

La documentación de SimpleDateFormat dice:

SimpleDateFormat no es thread-safe. Los usuarios deben crear una instancia independiente para cada subproceso.

Ahí tienes. Basta con crear el objeto SimpleDateFormat separado en cada subproceso y pasarlo al método.

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