You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android使用Joda Time解析日期抛出IllegalArgumentException问题求解

问题背景

方法预期逻辑:从Firestore读取最近一次盘点的日期数据,若距离当前时间间隔满24小时则执行*proceedWithInventoryMode()*方法。
对应实现代码:

private void checkIf24HourReached() {
    LocalDateTime now = LocalDateTime.now();
    LocalDateTime _24hrsBefore = now.minusDays(1);

    db.collection("Project").document(Prefs.getString("ManageID",
            GlobalObject._FIRESTORE_ID))
            .collection("inventoryMode")
            .document(GlobalObject._INVENTORY_MODE_DATA_ID)
            .get()
            .addOnSuccessListener(documentSnapshot -> {
                String lastInventoryEndDate = documentSnapshot.getString("date");
                Log.d("lastInventoryEndDate: ", lastInventoryEndDate);
                if (lastInventoryEndDate == null) {
                    proceedWithInventoryMode();
                } else {
                    if (lastInventoryEndDate.isEmpty()) {
                        proceedWithInventoryMode();
                    }
                    LocalDateTime lastInventoryDate = new LocalDateTime(lastInventoryEndDate);
                    if (_24hrsBefore.isAfter(lastInventoryDate)) {
                        proceedWithInventoryMode();
                    } else {
                        Toast.makeText(getContext(),
                                "Last Inventory ended less than a day ago.",
                                Toast.LENGTH_LONG).show();
                        Toast.makeText(getContext(),
                                "Last date: " + lastInventoryEndDate,
                                Toast.LENGTH_LONG).show();
                    }
                }
            })
            .addOnFailureListener(e -> Toast.makeText(getContext(),
                    "Date couldn't be read.",
                    Toast.LENGTH_LONG).show());

}

运行时抛出IllegalArgumentException异常,onSuccess()回调中打印的lastInventoryEndDate值为"13/07/2022 09:57:11",错误日志如下:

E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.nati.mvp.flowiusmanage, PID: 18644
java.lang.IllegalArgumentException: Invalid format: "13/07/2022 09:57:11" is malformed at "/07/2022 09:57:11"
    at org.joda.time.format.DateTimeParserBucket.doParseMillis(DateTimeParserBucket.java:187)
    at org.joda.time.format.DateTimeFormatter.parseMillis(DateTimeFormatter.java:826)
    at org.joda.time.convert.StringConverter.getPartialValues(StringConverter.java:87)
    at org.joda.time.LocalDateTime.<init>(LocalDateTime.java:414)
    at org.joda.time.LocalDateTime.<init>(LocalDateTime.java:358)
    at com.nati.mvp.flowiusmanage.fragments.inventoryFragments.InventoryModeFragment.lambda$checkIf24HourReached$2$InventoryModeFragment(InventoryModeFragment.java:157)
    at com.nati.mvp.flowiusmanage.fragments.inventoryFragments.-$$Lambda$InventoryModeFragment$_kMo6tPuE8p1PpNkIRJgZvJYet8.onSuccess(Unknown Source:6)
    at com.google.android.gms.tasks.zzm.run(com.google.android.gms:play-services-tasks@@18.0.1:1)
    at android.os.Handler.handleCallback(Handler.java:883)
    at android.os.Handler.dispatchMessage(Handler.java:100)
    at android.os.Looper.loop(Looper.java:264)
    at android.app.ActivityThread.main(ActivityThread.java:7581)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:980)
问题原因
  • 直接触发崩溃的原因:代码使用Joda Time的LocalDateTime(String)构造方法解析日期,该构造方法默认仅支持解析ISO标准格式(类似yyyy-MM-dd'T'HH:mm:ss)的字符串,但从Firestore读取到的日期值为13/07/2022 09:57:11,属于dd/MM/yyyy HH:mm:ss格式(斜杠分隔日/月/年),和默认解析规则不匹配,直接抛出IllegalArgumentException。
  • 隐藏逻辑漏洞:判断lastInventoryEndDate为空字符串的分支中,调用proceedWithInventoryMode()后没有加return终止流程,后续仍会执行日期解析逻辑,空字符串传入解析方法同样会触发格式异常。
修复方案
  • 针对现有dd/MM/yyyy HH:mm:ss格式的日期字符串,手动指定匹配的Joda Time格式化器完成解析,不要直接调用单字符串参数的默认构造方法。
  • 补全空值、空字符串判断分支的return逻辑,避免无效代码继续执行。
  • 增加解析异常捕获,避免特殊格式值导致崩溃。
  • 长期优化建议:后续在Firestore存储日期时,直接存储Long类型时间戳,读取后可以直接转成LocalDateTime,完全避免字符串格式不匹配的问题。

修复后的核心解析代码参考:

.addOnSuccessListener(documentSnapshot -> {
    String lastInventoryEndDate = documentSnapshot.getString("date");
    Log.d("lastInventoryEndDate: ", lastInventoryEndDate);
    // 空值、空字符串直接执行逻辑后返回,不往下走解析流程
    if (lastInventoryEndDate == null || lastInventoryEndDate.isEmpty()) {
        proceedWithInventoryMode();
        return;
    }
    try {
        // 指定和存储格式匹配的解析器:dd/MM/yyyy HH:mm:ss
        DateTimeFormatter formatter = DateTimeFormat.forPattern("dd/MM/yyyy HH:mm:ss");
        LocalDateTime lastInventoryDate = LocalDateTime.parse(lastInventoryEndDate, formatter);
        if (_24hrsBefore.isAfter(lastInventoryDate)) {
            proceedWithInventoryMode();
        } else {
            Toast.makeText(getContext(),
                    "Last Inventory ended less than a day ago.",
                    Toast.LENGTH_LONG).show();
            Toast.makeText(getContext(),
                    "Last date: " + lastInventoryEndDate,
                    Toast.LENGTH_LONG).show();
        }
    } catch (IllegalArgumentException e) {
        // 捕获格式解析异常,按无有效日期处理
        proceedWithInventoryMode();
    }
})

内容的提问来源于stack exchange,提问作者Alula48

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 11:27:14