在Android中解析日期时出现意外的副作用 [英] Unexpected side effects when parsing dates in Android

查看:99
本文介绍了在Android中解析日期时出现意外的副作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在各种Android项目中,我使用以下静态函数来解析日期,例如 1900-12-31 。当然,此功能应该是确定性的-但事实并非如此。为什么?

In various Android projects, I use the following static function to parse dates such as 1900-12-31. Of course, this function should be deterministic - but it turns out it is not. Why?

通常,它会将日期 2010-10-30 解析为正确的<$拥有该值的c $ c> Date 实例。但是我注意到,当我同时运行 IntentService 并解析某些日期时,此函数将与上述相同的日期解析为 1983- 01-20 ,这是 IntentService 中解析的日期之一。

Normally, it parses the date 2010-10-30, for example, to the correct Date instance holding that value. But I have noticed that when I have an IntentService running at the same time and parsing some dates, this function parses the same date as above to 1983-01-20, which is one of the dates parsed in the IntentService. How can this happen?

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

编辑:我在活动 onCreate(),在此我启动一个 AsyncTask 做这份工作。在活动 onStop()中,启动了后台服务,其功能相同。当我关闭应用程序(onStop())并快速重新启动它(onCreate())时,似乎两者都同时运行,并且发生了错误。

I do the parsing in my Activity's onCreate() where I start an AsyncTask that does the job. In the Activity's onStop(), a background service is started which does the same job. When I close the app (onStop()) and quickly restart it (onCreate()), both seem to be running simultaneously and the error occurrs.

推荐答案

SimpleDateFormat 说:


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

SimpleDateFormat is not thread-safe. Users should create a separate instance for each thread.

您去了。只需在每个线程中分别创建 SimpleDateFormat 对象,然后将其传递给该方法即可。

There you go. Just create the SimpleDateFormat object separately in each thread and pass it to the method.

这篇关于在Android中解析日期时出现意外的副作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆