在Android中解析日期时出现意外的副作用

时间:2013-01-13 23:47:13

标签: android android-date

在各种Android项目中,我使用以下静态函数来解析1900-12-31等日期。当然,这个功能应该是确定性的 - 但事实证明它不是。为什么呢?

通常,它会将日期2010-10-30解析为保存该值的正确Date实例。但我注意到,当我同时运行IntentService并解析某些日期时,此函数会将上述相同的日期解析为1983-01-20,这是IntentService中解析的日期之一。 1}}。怎么会发生这种情况?

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;
}

修改:我在Activity的{​​{1}}进行解析,在那里我开始onCreate()来完成这项工作。在AsyncTask的{​​{1}}中,启动后台服务,该服务执行相同的工作。当我关闭应用程序(onStop())并快速重新启动它(onCreate())时,两者似乎同时运行并发生错误。

1 个答案:

答案 0 :(得分:5)

SimpleDateFormat的文档说:

  

SimpleDateFormat不是线程安全的。用户应该创建一个单独的   每个线程的实例。

你去吧。只需在每个线程中单独创建SimpleDateFormat对象并将其传递给方法。