【问题标题】:Converting from Instant to XMLGregorianCalendar and vice-versa without losing precision从 Instant 转换为 XMLGregorianCalendar,反之亦然,而不会丢失精度
【发布时间】:2021-06-08 04:26:05
【问题描述】:

使用java.time.Instantjavax.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

【问题讨论】:

    标签: java java.time.instant xmlgregoriancalendar


    【解决方案1】:

    为什么这个测试没有通过?

    您的XMLGregorianCalendar 已完全精确到您的Instant。您转换回Instant 是有损的。您正在通过调用.toGregorianCalendar() 转换为GregorianCalendarGreogrianCalendar 只有毫秒精度,所以这是你失去精度的地方。

    如何解决?

    就像您在第一次转换时通过 String 一样,您也可以对相反的转换执行相同的操作:

        Instant convertedInstant = Instant.parse(xmlGregorianCalendar.toString());
    

    现在您的测试通过了(在我的 Java 9 上通过了)。

    结束语

    Instant 的秒精度高达小数点后 9 位(即纳秒)。 XMLGregorianCalendar 具有几乎无限的精度。因此,如果您已将 Instant 转换为 XMLGregorianCalendar,则您知道它的精度不超过 9 位小数,因此您可以安全地将其转换回来。另一方面,如果您应该从某个地方获得具有更高精度(10 位或更多)的XMLGregorianCalendar,那么我向您展示的转换将失败并返回DateTimeParseException

    【讨论】:

      猜你喜欢
      • 2010-10-29
      • 2012-10-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-15
      • 2020-10-24
      • 2014-01-23
      • 1970-01-01
      相关资源
      最近更新 更多