Scala后端解析Angular发送的TZ格式日期SimpleDateFormat报错如何解决
问题原因
报错核心是两处逻辑不匹配:
- 解析模式与输入格式不匹配:Angular发送的是ISO 8601标准UTC时间格式
2021-09-06T11:25:39.000Z,其中T是日期和时间的分隔字面量,末尾Z代表UTC时区标识。你当前使用的解析模式yyyy-MM-dd HH:mm:ss既没有匹配T字符,也没有处理毫秒部分和时区标识,因此会抛出解析异常。 - 解析和格式化复用同一个模式串:你现有代码用同一个模式串同时做输入解析和输出格式化,不符合输入格式与目标输出格式不同的场景要求。
解决方案
SimpleDateFormat本身是非线程安全类,多线程环境下复用容易出现诡异的解析错误,优先推荐使用Java 8及以上版本内置的java.time时间库(Scala可直接调用)处理时间逻辑。
方案1:使用java.time库(推荐)
Instant原生支持解析带Z标识的ISO 8601格式时间,无需手动编写解析模式串:
import java.time.Instant import java.time.format.DateTimeFormatter import java.time.ZoneId def formattedDate(input: String, targetFormat: String = "yyyy-MM-dd HH:mm:ss", zone: ZoneId = ZoneId.systemDefault()): String = { val instant = Instant.parse(input) DateTimeFormatter.ofPattern(targetFormat) .withZone(zone) .format(instant) }
如果需要输出特定时区的时间,比如北京时间,调用时传入ZoneId.of("Asia/Shanghai")即可。
方案2:兼容旧代码使用SimpleDateFormat
如果必须使用SimpleDateFormat,需要单独定义解析用的模式串,且不要在多线程场景下复用实例:
import java.text.SimpleDateFormat import java.util.TimeZone def formattedDate(input: String, targetFormat: String = "yyyy-MM-dd HH:mm:ss"): String = { // 匹配ISO 8601带Z标识的解析模式 val parseFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX") parseFormat.setTimeZone(TimeZone.getTimeZone("UTC")) val date = parseFormat.parse(input) // 输出格式可按需自定义 val outputFormat = new SimpleDateFormat(targetFormat) outputFormat.format(date) }
内容的提问来源于stack exchange,提问作者AlleXyS
相关产品推荐
相关产品推荐

