将java.sql.Timestamp转换为javax.xml.datatype.XMLGregorianCalendar,同时不丢失纳秒。
将java.sql.Timestamp转换为javax.xml.datatype.XMLGregorianCalendar,同时不丢失纳秒。
如何将java.sql.Timestamp
转换为javax.xml.datatype.XMLGregorianCalendar
是最清洁的方法?
考虑到XMLGregorianCalendar
带有BigDecimal
精度的小数秒,因此没有精度损失,但我不确定在给定java.sql.Timestamp
对象的情况下应该设置哪个时区至XMLGregorianCalendar
对象。
在SO上已经有一个回答,介绍了如何将java.util.Date
转换为XMLGregorianCalendar
,因此我可以将我的Timestamp
转换为java.util.Date
,但这将导致在亚毫秒级别的精度损失,这是不必要的,因为目标数据类型(XMLGregorianCalendar
)可以容纳源数据类型(Timestamp
)的纳秒分量
admin 更改状态以发布 2023年5月20日
java.sql.Timestamp
存储的是自1970年1月1日00:00:00 GMT/UTC以来的毫秒数加上纳秒数。因此,除非你在两者之间做了什么愚蠢的事情,我建议你根据 XMLGregorianCalendar文档 将时区设置为0(UTC)。
我是这样做的:
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