Reputation: 3829
I'm trying to fetch timestamp values from a database, convert them to Calendar, and convert them back to Timestamp, but they lose their precision.
Here's the code to reproduce the problem
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());
}
}
Here is the sample result of conversion
BEFORE 2012-10-18 14:30:13.362001
AFTER 2012-10-18 14:30:13.362
It loses its precision. What do I do to keep the decimal value as it is?
Upvotes: 32
Views: 68559
Reputation: 340098
In Java 8 and later we now have a solution: the new java.time framework is built in. Defined by JSR 310, inspired by Joda-Time, extended by the ThreeTen-Extra project.
This new framework has nanosecond resolution. That's enough to handle the old java.util.Date values, Joda-Time values, both being milliseconds. And it's enough to handle the microseconds used by some databases such as Postgres. Some databases such as H2 use nanoseconds. So java.time can handle it all, or least all the mainstream situations. The only exceptions would be niche scientific or engineering situations.
With Java 8, the old classes got new methods for converting to/from java.time. On java.sql.Timestamp use the new toInstant
and fromInstant
methods. The Instant
class contains a count of nanoseconds from epoch, first moment of 1970 UTC (basically, see class doc for details).
From an Instant
you can get a ZonedDateTime
object.
java.sql.Timestamp ts = myResultSet.getTimestamp( 1 );
Instant instant = ts.toInstant();
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( zoneId );
Upvotes: 8
Reputation: 425328
You are setting the time in milliseconds, but your input precision is in microseconds, so of course you are going to lose any precision finer than milliseconds.
Calendar doesn't support finer granularity than milliseconds. There is no work-around.
Upvotes: 31