为何Instant.now()的字符串格式有时会不一致?
问题根源与解决方案
这问题我之前也踩过坑!其实你看到的格式不一致,完全是Instant.toString()的输出规则导致的:
- 当Instant的毫秒部分为0时,它的toString方法会省略毫秒部分,输出类似
2018-05-25T18:56:09Z的格式; - 当毫秒部分非0时,才会显示三位毫秒值,比如
2018-05-25T20:06:58.900Z。
而你的代码里用SimpleDateFormat指定的格式是yyyy-MM-dd'T'HH:mm:ss.SSSX,要求必须有毫秒部分,所以碰到不带毫秒的字符串时,自然会抛出解析异常。
更重要的是:你的代码绕了大弯,还用到了过时的API
SimpleDateFormat和Date都是Java 8之前的旧API,不仅线程不安全,处理时区和日期转换也很麻烦。既然你已经在使用Instant(Java 8+的新日期API),直接用java.time包的工具类就能完美解决问题,根本不需要先把Instant转成字符串再解析一遍!
正确的写法示例
直接把Instant转换为日期并格式化,一步到位:
String PROPER_DATE_FORMAT = "yyyy-MM-dd"; // 使用Java 8+的DateTimeFormatter,线程安全且更易用 DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern(PROPER_DATE_FORMAT); // Instant是UTC时间,先转换为UTC时区的ZonedDateTime,再提取LocalDate String formattedDate = dateFormatter.format( Instant.now().atZone(ZoneOffset.UTC).toLocalDate() );
如果你的业务需要用系统默认时区而不是UTC,只需要把ZoneOffset.UTC换成ZoneId.systemDefault()即可。
额外提醒
永远不要再用「日期对象→字符串→解析回日期对象」这种绕圈的方式处理日期,直接用java.time API的类型转换,既高效又能避免各种格式匹配的坑。
内容的提问来源于stack exchange,提问作者Vicky
相关产品推荐
相关产品推荐

