
android 使用 simpledateformat 解析如 "wed jul 12 2023 23:58:20 gmt+0000 (coordinated universal time)" 这类英文日期时,若设备系统语言非英语(如阿拉伯语),因 locale.getdefault() 匹配不到对应英文缩写(如 "wed"、"jul"),将抛出 unparseable date 异常;强制指定 locale.english 即可解决。
android 使用 simpledateformat 解析如 "wed jul 12 2023 23:58:20 gmt+0000 (coordinated universal time)" 这类英文日期时,若设备系统语言非英语(如阿拉伯语),因 locale.getdefault() 匹配不到对应英文缩写(如 "wed"、"jul"),将抛出 unparseable date 异常;强制指定 locale.english 即可解决。
在 Android 开发中,SimpleDateFormat 对日期格式字符串的解析高度依赖 Locale —— 它不仅影响数字格式、星期/月份名称的显示顺序,更关键的是决定 EEE(星期缩写)、MMM(月份缩写)等模式所匹配的实际文本。例如:
-
"Wed"是英语环境下的星期三缩写; - 在阿拉伯语(
Locale.ARABIC)或中文(Locale.CHINESE)环境下,SimpleDateFormat会尝试匹配"الأربعاء"或"周三",而非"Wed"。
因此,当你传入一个固定为英文格式的日期字符串(如 JavaScript new Date().toString() 输出),却使用 Locale.getDefault()(可能为 ar_EG、zh_CN 等),解析必然失败:
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.getDefault())
// ✅ 正确:明确声明输入为英文格式,强制使用 Locale.ENGLISH
val sdf = SimpleDateFormat("EEE MMM dd yyyy HH:mm:ss ", Locale.ENGLISH)
⚠️ 注意:原始字符串中还包含 GMT+0000 (Coordinated Universal Time) 部分,而你的 pattern "EEE MMM dd yyyy HH:mm:ss " 未覆盖时区信息。虽然 SimpleDateFormat 在部分版本中会忽略多余内容(“宽松模式”),但该行为不可靠且已过时。为健壮性考虑,建议:
-
截断冗余时区描述(推荐,简单可靠):
val cleanInput = input.substringBeforeLast(" GMT").trim() // → "Wed Jul 12 2023 23:58:20" -
或扩展 pattern 支持时区(需注意
z和Z的区别):// GMT+0000 可用 'Z'(RFC 822 时区,如 +0000),但不支持括号内全称 val sdf = SimpleDateFormat("EEE MMM dd yyyy HH:mm:ss Z", Locale.ENGLISH) val cleanInput = input.replace(Regex("\s*\([^)]+\)"), "") // 移除 "(Coordinated Universal Time)"
✅ 最终推荐写法(简洁、安全、兼容性强):
fun parseEnglishDateTime(input: String): Long {
return try {
// 移除括号内的时区全称,保留 GMT+0000(可被 'Z' 解析)
val clean = input.replace(Regex("\s*\([^)]+\)"), "").trim()
val sdf = SimpleDateFormat("EEE MMM dd yyyy HH:mm:ss Z", Locale.ENGLISH)
sdf.parse(clean)?.time ?: -1L
} catch (e: ParseException) {
-1L
}
}
? 总结:
-
永远不要对固定语言格式的输入依赖
Locale.getDefault(); - 显式指定
Locale.ENGLISH是解析英文日期字符串的黄金准则; - 处理第三方(如 JS、后端)返回的日期字符串时,优先清洗或标准化格式,避免依赖
SimpleDateFormat的模糊匹配; - (进阶建议)在新项目中优先使用
java.time(如DateTimeFormatter.ofPattern(...).withLocale(Locale.ENGLISH)),它更线程安全、设计更合理,且SimpleDateFormat已被标记为 legacy。











