Kotlin解析Zulu格式日期字符串时时间莫名多出5分钟问题排查
问题根源:日期解析格式符错误
你的代码里,解析Zulu时间的SimpleDateFormat模式存在错误:
val readLocalDateFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.sss'Z'")
在SimpleDateFormat的规则里,小写的s代表秒,而毫秒对应的格式符是大写的S。你写的.sss会把原时间字符串里的.325当成秒的小数部分(即28.325秒),导致解析出的时间比实际时间多了325秒(5分25秒)。后续转时区格式化后,就出现了12:34的错误结果。
修正方案
方案1:修复SimpleDateFormat的格式模式
把解析模式里的.sss改成.SSS即可:
try { // 修正毫秒格式符为大写S val readLocalDateFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") readLocalDateFormat.timeZone = TimeZone.getTimeZone("UTC") val writeLocalDateFormat = SimpleDateFormat("yyyy-MM-dd HH:mm") writeLocalDateFormat.timeZone = TimeZone.getTimeZone("America/Halifax") return writeLocalDateFormat.format(readLocalDateFormat.parse(dateStr)) } catch (e: Exception) { Log.e(TAG, "Failed to parse date: $dateStr") return dateStr }
修正后解析出的时间为正确的2022-11-21T16:29:28.325 UTC,转America/Halifax时区后格式化就能得到预期的2022-11-21 12:29。
方案2:使用Java 8+的java.time API(推荐)
SimpleDateFormat是线程不安全的过时API,推荐使用Java 8引入的java.time包下的类,这类API设计更合理,也更可靠:
import java.time.Instant import java.time.ZoneId import java.time.format.DateTimeFormatter fun formatZuluToTimeZone(dateStr: String): String { return try { // 直接解析Zulu格式字符串为Instant val instant = Instant.parse(dateStr) // 指定目标时区 val targetZone = ZoneId.of("America/Halifax") // 定义输出格式 val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm") // 转换时区并格式化 instant.atZone(targetZone).format(formatter) } catch (e: Exception) { Log.e(TAG, "Failed to parse date: $dateStr") dateStr } }
这种方式不需要手动编写解析格式,Instant.parse会自动处理Zulu格式,代码更简洁且不易出错。
内容的提问来源于stack exchange,提问作者owenlejeune
相关产品推荐
相关产品推荐

