Wil*_*ino 30 java timestamp calendar
我正在尝试从数据库中获取时间戳值,将它们转换为日历,然后将它们转换回时间戳,但它们会失去精度.
这是重现问题的代码
import java.sql.Timestamp;
import java.util.Calendar;
public class Test {
public static void main(String[] args)
{
Timestamp timestamp = new Timestamp(112, 10, 5, 15, 39, 11, 801000000);
System.out.println("BEFORE "+timestamp.toString());
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(timestamp.getTime());
timestamp = new Timestamp(calendar.getTimeInMillis());
System.out.println("AFTER "+timestamp.toString());
}
}
Run Code Online (Sandbox Code Playgroud)
以下是转换的示例结果
BEFORE 2012-10-18 14:30:13.362001
AFTER 2012-10-18 14:30:13.362
Run Code Online (Sandbox Code Playgroud)
它失去了它的精确度.如何保持小数值不变?
Boh*_*ian 30
您设置的时间以毫秒为单位,但您的输入精度以微秒为单位,因此您将失去任何精度超过毫秒的精度.
Calendar不支持比毫秒更精细的粒度.没有解决方法.
在Java 8及更高版本中,我们现在有了一个解决方案:内置了新的java.time框架.由JSR 310定义,受Joda-Time的启发,由ThreeTen-Extra项目扩展.
这个新框架具有纳秒分辨率.这足以处理旧的java.util.Date值,Joda-Time值,都是毫秒.它足以处理一些数据库(如Postgres)使用的微秒.一些数据库如H2使用纳秒.所以java.time可以处理所有这些,或者至少所有主流情况.唯一的例外是利基科学或工程情况.

使用Java 8,旧类获得了转换为/从java.time转换的新方法.在java.sql.Timestamp上使用new toInstant和fromInstant方法.本Instant类包含的时代,1970年UTC的第一刻纳秒的计数(基本上,详见类文档).
从一个Instant你可以得到一个ZonedDateTime对象.
java.sql.Timestamp ts = myResultSet.getTimestamp( 1 );
Instant instant = ts.toInstant();
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( zoneId );
Run Code Online (Sandbox Code Playgroud)