首页 > 解决方案 > 为什么从字符串到日期的转换不正确?

问题描述

在我的 Kotlin 代码中:

   const val TS_DATE_PATTERN = "yyyy-MM-dd'T'HH:mm:ss.SSS"
   val ts = responseJsonObject.get("TS").getAsString()
   val tsDate = SimpleDateFormat(TS_DATE_PATTERN).parse(ts)
   val tsDateAsString = SimpleDateFormat(TS_DATE_PATTERN).format(tsDate)
   logger.info("ts = " + ts + " -> tsDate = " + tsDate + " -> tsDateAsString = " + tsDateAsString)

这里是(为便于阅读而格式化)结果:

ts             = 2019-01-14T22:56:30.429582 
tsDate         = Mon Jan 14 23:03:39 EET 2019 
tsDateAsString = 2019-01-14T23:03:39.582

如您所见,tstsDateAsString有不同的时间,尽管它们来自同一个起点。

例如ts = 22:56:30,但在tsDateAsString = 23:03:39

为什么?

标签: datetimekotlin

解决方案


作为建议:尽可能使用java.time-utilities。

SimpleDateFormat对毫秒有特殊处理。由 解析的所有内容都S被视为毫秒。只要您处理 3 位毫秒,一切都很好(您甚至可以只使用单个S(ie .S) 来解析它们),但是如果您使用 6 位毫秒作为输入,那么您也会得到一个6 位毫秒 (!) 值。

那么 6 位数毫秒实际上是 3 位数秒 + 3 位数毫秒。这就是偏差的来源。

如何解决?那么要么缩短输入时间字符串并失去一些精度,要么使用DateTimeFormatter与您的输入匹配的模式代替首选,即yyyy-MM-dd'T'HH:mm:ss.SSSSSS

val TS_DATE_PATTERN = "yyyy-MM-dd'T'HH:mm:ss.SSSSSS"
val formatter = DateTimeFormatter.ofPattern(TS_DATE_PATTERN)

val tsDate = formatter.parse(ts) // now the value as you would expect it...

将其转换为 aTimeStamp将按如下方式工作:

Timestamp.valueOf(LocalDateTime.from(tsDate))

推荐阅读