首页 > 解决方案 > Android SimpleDateFormat.format 给出错误的数字数量,如 Minute “0040” 随机

问题描述

我有一个适用于 android 的应用程序,它有一个自定义的日志格式,我在前面加上 Date 以便更好地搜索。目前我正在使用 SimpleDateFormat 但结果不一致。

这种不一致的几个例子,它给了我:

2018/10/11 10:40:21.229 ____Verbose:
2018/0010/0011 0010:40:21.230 ____Verbose:
2018/10/11 10:40:21.232 ____Verbose:
...
2018/10/11 10:40:42.784 ____Verbose:
2018/10/11 010:040:042.786 ____Verbose:
2018/10/11 10:40:42.786 ____Verbose:

我正在使用的代码是:

private static final DateFormat LOGDATEFULL = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss.SSS");
private static String strErrorLevel(int errorLevel){
    if (errorLevel == VERBOSE  ) return " ____ VERBOSE: ";
    if (errorLevel == DEBUG    ) return " ____ DEBUG  : ";
    if (errorLevel == INFO     ) return " _.._ INFO   : ";
    if (errorLevel == WARN     ) return " _--_ WARN   : ";
    if (errorLevel == ERROR    ) return " _!!_ ERROR  : ";
    if (errorLevel == ANALYTICS) return " _++_ ANALYTC: ";
    return                              " _**_ ASSERT : ";
}
public static void customLog(String message, int level){
    Date currDate = Calendar.getInstance().getTime();
    Log.d(LOGDATEFULL.format(currDate) + " " + strErrorLevel(level) + message);
}

我的系统语言环境是葡萄牙语巴西 (pt-BR),当从主线程调用和从其他线程调用时都会发生这种情况。

除了创建一个手动制作字符串的函数之外,还有其他解决方案吗?

顺便说一句,即使在为“Output_2018-010-11.txt”之类的文件生成名称时也会发生这种情况。

答:这确实是Tom Glelloman 所指出的,在我使用 SimpleDateFormat 的所有地方,这是我唯一拥有的,一次可能被多个线程访问。我选择 Tom G 的答案是为了在现有代码中实现的实用性。

谢谢

标签: javaandroidsimpledateformat

解决方案


如果您使用SimpleDateFormat来自多个线程的实例,则可能存在竞争条件,并且正如已指出的那样,该类不是线程安全的。来自官方文档

日期格式不同步。建议为每个线程创建单独的格式实例。如果多个线程同时访问一个格式,它必须在外部同步。

您应该同步对该实例的访问:

public static void customLog(String message, int level){
    Date currDate = Calendar.getInstance().getTime();
    synchronized(LOGDATEFULL) {
        Log.d(LOGDATEFULL.format(currDate) + " " + strErrorLevel(level) + message);
    }
}

推荐阅读