将java.sql.Timestamp转换为javax.xml.datatype.XMLGregorianCalenda



java.sql.Timestamp转换为javax.xml.datatype.XMLGregorianCalendar的最干净方法是什么?

鉴于XMLGregorianCalendar在小数秒内具有BigDecimal精度,因此不会损失精度,但是我不确定应该在XMLGregorianCalendar对象上设置哪个时区,因为java.sql.Timestamp与时区无关。

SO 上有一个关于如何将java.util.Date转换为XMLGregorianCalendar的答案,这样我就可以将我的Timestamp投射到java.util.Date但这会导致亚毫秒范围内的精度损失,这是不必要的,因为目标数据类型 (XMLGregorianCalendar) 可以容纳源数据类型 (Timestamp 的纳秒分量)。

我这样做:

import java.math.BigDecimal;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.Date;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;
public class ApiRuntime {
    public static void main(String[] args) throws Exception {
        Timestamp ts = new Timestamp(new Date().getTime());
        ts.setNanos(123456789);
        LocalDateTime ldt = ts.toLocalDateTime();
        XMLGregorianCalendar cal = DatatypeFactory.newInstance().newXMLGregorianCalendar();
        cal.setYear(ldt.getYear());
        cal.setMonth(ldt.getMonthValue());
        cal.setDay(ldt.getDayOfMonth());
        cal.setHour(ldt.getHour());
        cal.setMinute(ldt.getMinute());
        cal.setSecond(ldt.getSecond());
        cal.setFractionalSecond(new BigDecimal("0." + ldt.getNano()));
        System.out.println("Timestamp::" + ts);
        System.out.println("Calendar:::" + cal);
    }
}

该示例输出:

Timestamp::2015-08-25 20:59:35.123456789  
Calendar:::2015-08-25T20:59:35.123456789

java.sql.Timestamp持有自 1970 年 1 月 1 日 00:00:00 GMT/UTC + nanos 以来的米利斯数量。因此,除非您在两者之间做任何愚蠢的事情,否则我建议根据XMLGregorianCalendar文档将时区设置为0(UTC)。

AlexCG 答案在某些情况下(当我们给出的 nanos 数字少于 9 位时)不太正常工作,例如,当我们将 nanos 设置为 25 时,我们会收到如下输出:

Timestamp::2020-01-02 16:30:01.000000025
Calendar:::2020-01-02T16:30:01.25

这不是真的。我稍微修改了一下这种方法,现在是:

    @Test
    public void convertLocalDataTimeToXmlGCal() throws Exception {
        Timestamp ts = new Timestamp(new Date().getTime());
        ts.setNanos(25);
        LocalDateTime ldt = ts.toLocalDateTime();
        XMLGregorianCalendar cal = DatatypeFactory.newInstance().newXMLGregorianCalendar();
        cal.setYear(ldt.getYear());
        cal.setMonth(ldt.getMonthValue());
        cal.setDay(ldt.getDayOfMonth());
        cal.setHour(ldt.getHour());
        cal.setMinute(ldt.getMinute());
        cal.setSecond(ldt.getSecond());
        String nanos = "0." + StringUtils.leftPad(String.valueOf(ldt.getNano()), 9, '0');
        cal.setFractionalSecond(new BigDecimal(nanos));
        System.out.println("Timestamp::" + ts);
        System.out.println("Calendar:::" + cal);
    }

现在输出是正确的:

Timestamp::2020-01-02 16:33:02.000000025
Calendar:::2020-01-02T16:33:02.000000025

Apache Commons 库是必需的。

相关内容

最新更新