将java.sql.Timestamp转换为javax.xml.datatype.XMLGregorianCalendar而不会丢失nanos

时间:2013-11-03 19:18:28

标签: java

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

鉴于XMLGregorianCalendar小数秒的精度为BigDecimal,精度没有任何损失,但是我不确定在XMLGregorianCalendar对象设置java.sql.Timestamp对象的时区。{ 1}}与时区无关。

how to convert java.util.Date to XMLGregorianCalendar上有关于SO的答案,所以我可以将Timestamp转换为java.util.Date但这会导致亚毫秒范围内的精度损失,这是不必要的target数据类型(XMLGregorianCalendar)可以保存源数据类型(Timestamp)的纳秒组件。

3 个答案:

答案 0 :(得分:3)

我这样做:

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

答案 1 :(得分:0)

java.sql.Timestamp保留自1970年1月1日00:00:00 GMT / UTC + nanos以来的毫秒数。因此,除非你在中间做任何事情,否则我建议你based on the XMLGregorianCalendar docs将时区设置为0(UTC)。

答案 2 :(得分:0)

AlexCG answer在某些情况下(当我们给出小于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库。