如何解决在不损失精度的情况下从 Instant 转换为 XMLGregorianCalendar 反之亦然
使用 java.time.Instant
和 javax.xml.datatype.XMLGregorianCalendar
,我试图在不损失精度的情况下从一种转换到另一种。
为什么这个测试没有通过以及如何修复它?
class FooTest {
@Test
void shouldConvertBackToSameInstant() throws DatatypeConfigurationException {
Instant initialInstant = Instant.Now();
XMLGregorianCalendar xmlGregorianCalendar = DatatypeFactory.newInstance().newXMLGregorianCalendar(String.valueOf(initialInstant));
Instant convertedInstant = xmlGregorianCalendar.toGregorianCalendar().toInstant();
assertEquals(initialInstant,convertedInstant);
}
}
org.opentest4j.AssertionFailedError:
Expected :2021-03-10T08:34:30.700715078Z
Actual :2021-03-10T08:34:30.700Z
解决方法
为什么这个测试没有通过?
您的 XMLGregorianCalendar
已获得您的 Instant
的全部精度。有损的是您向 Instant
的转换。您正在通过调用 GregorianCalendar
转换为 .toGregorianCalendar()
。 GreogrianCalendar
只有毫秒精度,所以这就是你失去精度的地方。
如何解决?
就像您在第一次转换时经历 String
一样,您也可以对相反的转换执行相同的操作:
Instant convertedInstant = Instant.parse(xmlGregorianCalendar.toString());
现在您的测试通过了(它在我的 Java 9 上通过)。
结束语
Instant
在秒(即纳秒)上的精度高达 9 位小数。 XMLGregorianCalendar
具有几乎无限的精度。因此,如果您已将 Instant
转换为 XMLGregorianCalendar
,您知道它的精度不能超过 9 位小数,因此您可以安全地将其转换回来。另一方面,如果您应该从某个地方获得精度更高(10 位小数或更多)的 XMLGregorianCalendar
,那么我向您展示的转换将失败并显示 DateTimeParseException
。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。