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

Android API 34下SimpleDateFormat解析GMT日期抛ParseException求助

问题分析

在Android API Level 34中,SimpleDateFormat的解析行为更严格——默认会使用设备系统Locale,若系统Locale非英文,就无法匹配输入字符串里的英文星期(Mon)和月份(Sep)缩写,从而抛出ParseException。API33及以下版本对Locale兼容更宽松,因此未触发该问题。

解决方法

方法1:为SimpleDateFormat指定英文Locale

直接修改现有代码,显式传入Locale.ENGLISH,确保解析时用英文规则匹配日期格式:

fun calculateAge(dateString: String): String {
    // 显式指定英文Locale,避免系统Locale影响解析
    val dateFormat = SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.ENGLISH)
    dateFormat.timeZone = TimeZone.getTimeZone("GMT")
    val inputDate = dateFormat.parse(dateString) ?: return "Invalid date" // 增加空判断防止NPE
    val currentCalendar = Calendar.getInstance()
    val inputCalendar = Calendar.getInstance().apply { time = inputDate }
    
    val years = currentCalendar.get(Calendar.YEAR) - inputCalendar.get(Calendar.YEAR)
    val months = currentCalendar.get(Calendar.MONTH) - inputCalendar.get(Calendar.MONTH)
    val days = currentCalendar.get(Calendar.DAY_OF_MONTH) - inputCalendar.get(Calendar.DAY_OF_MONTH)

    return when {
        years > 0 -> "$years years"
        months > 0 -> "$months months"
        days > 0 -> "$days days"
        else -> "0 days"
    }
}

方法2:迁移到Java 8+的java.time API(推荐)

SimpleDateFormat和Calendar属于过时且线程不安全的类,Android API 26+(Android 8.0)原生支持java.time现代日期API,API26以下可通过开启Core Library Desugaring兼容。

修改后的代码如下:

import java.time.ZonedDateTime
import java.time.format.DateTimeFormatter
import java.time.temporal.ChronoUnit

fun calculateAge(dateString: String): String {
    // 使用预定义的RFC_1123格式,完全匹配输入的日期字符串
    val formatter = DateTimeFormatter.RFC_1123_DATE_TIME
    val inputDate = ZonedDateTime.parse(dateString, formatter)
    val currentDate = ZonedDateTime.now(inputDate.zone)

    val years = ChronoUnit.YEARS.between(inputDate, currentDate)
    val months = ChronoUnit.MONTHS.between(inputDate, currentDate) % 12
    val days = ChronoUnit.DAYS.between(inputDate, currentDate) % 30 // 如需精确天数可调整计算逻辑

    return when {
        years > 0 -> "$years years"
        months > 0 -> "$months months"
        days > 0 -> "$days days"
        else -> "0 days"
    }
}

该方案稳定性更高、可读性更强,且无线程安全问题,是长期维护的最优选择。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 08:01:23