
当使用 SimpleDateFormat 解析类似 "Wed Jul 12 2023 23:58:20 GMT+0000 (Coordinated Universal Time)" 的英文日期字符串时,若设备系统语言非英文(如阿拉伯语),因 Locale.getDefault() 导致月份/星期缩写不匹配,将抛出 Unparseable date 异常;强制指定 Locale.ENGLISH 即可可靠解析。
当使用 simpledateformat 解析类似 "wed jul 12 2023 23:58:20 gmt+0000 (coordinated universal time)" 的英文日期字符串时,若设备系统语言非英文(如阿拉伯语),因 `locale.getdefault()` 导致月份/星期缩写不匹配,将抛出 unparseable date 异常;强制指定 `locale.english` 即可可靠解析。
该问题本质是 日期格式与 Locale 不匹配:SimpleDateFormat 的模式 "EEE MMM dd yyyy HH:mm:ss" 中,EEE(如 "Wed")和 MMM(如 "Jul")均为英文缩写,但 Locale.getDefault() 在阿拉伯语等非英语环境下会尝试按本地化规则(如 "الأربعاء"، "يوليو")去匹配输入,自然失败。
✅ 正确做法是显式指定 Locale.ENGLISH,确保解析器严格按英文缩写进行匹配:
val input = "Wed Jul 12 2023 23:58:20 GMT+0000 (Coordinated Universal Time)"
val sdf = SimpleDateFormat("EEE MMM dd yyyy HH:mm:ss", Locale.ENGLISH)
val time = try {
sdf.parse(input)?.time ?: -1L
} catch (e: ParseException) {
-1L
}
⚠️ 注意事项:
- 仅靠修改
Locale仍无法处理完整时区部分(GMT+0000 (Coordinated Universal Time)),因当前模式未包含时区字段。若需完整解析并保留时区信息,推荐升级至java.timeAPI(Android API 26+)或使用ThreeTenABP(兼容低版本):// 推荐(API 26+) val formatter = DateTimeFormatter.ofPattern("EEE MMM dd yyyy HH:mm:ss 'GMT'XX", Locale.ENGLISH) val zdt = ZonedDateTime.parse(input.replace(" (Coordinated Universal Time)", ""), formatter) - 若必须支持旧版 Android 且需解析完整字符串,可先预处理移除括号内描述(如正则
\s*\([^)]*\)),再用Locale.ENGLISH解析核心时间部分。 - 永远避免依赖
Locale.getDefault()解析固定语言格式的字符串——这是导致国际化场景下日期解析崩溃的常见根源。
总结:日期格式字符串的语言必须与 Locale 严格一致。对于硬编码英文日期(如服务器返回、日志时间戳),务必显式传入 Locale.ENGLISH,而非默认本地环境。











