Can use Jackson with nanosecond value
I've had the scariest time to deal with nanoseconds when parsing from object to json and vice versa. I've created the simplest use of Jackson and I can't get nanoseconds. Below is my demo. There are three important statements in the quickxml FAQ that are relevant to my case. The first two give me a trick to get the job done, and the third says not to use sql.Date
but sql.timestamp
is "son sql.Date
. "
Problems:
First,
mapper.configure(DeserializationFeature.READ_DATE_TIMESTAMPS_AS_NANOSECONDS,true)
they @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss.SSSSSS")
don't work at all. I can post false
, true
not even use mapper.configure
, use or not @JsonFormat
, and the result is the same,
Second, if I try only Deserialize, I mean put the value 2015-01-07 11:37:52.390452
in user.json
and just run mapper.readValue
, I get the value 2015-01-07 11:44:22.452
, so I miss the exact value because Jacskon rounds.
from http://wiki.fasterxml.com/JacksonFAQDateHandling
1 - Feature.WRITE_DATES_AS_TIMESTAMPS, false); which disallow the use of timestamps (numbers), and instead use [ISO-8601] -computer notation, which outputs something like "1970-01-01T00: 00: 00,000 + 0000".
2 - You can customize the formatting by passing java.text.DateFormat
3 - Please DO NOT use java.sql.Date, ever!
// pojo
package com.jim.core;
import java.sql.Timestamp;
import com.fasterxml.jackson.annotation.JsonFormat;
public class User {
@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss.SSSSSS")
private Timestamp tsFirstTry;
private Timestamp tsSecondTry;
@Override
public String toString() {
return "User [tsFirstTry=" + tsFirstTry + ", tsSecondTry=" + tsSecondTry + "]";
}
//getters and setters
}
// main class
package com.jim.core;
import java.io.File;
import java.io.IOException;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
public class Main {
public static void main(String[] args) {
User user = new User();
user.setTsFirstTry(Timestamp.valueOf(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSSSS").format(new Date())));
user.setTsSecondTry(Timestamp.valueOf(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSSSS").format(new Date())));
System.out.println("firstTryValue = "+ Timestamp.valueOf(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSSSS").format(new Date())));
System.out.println("secondTryValue = "+ Timestamp.valueOf(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSSSS").format(new Date())));
ObjectMapper mapper = new ObjectMapper();
try {
//mapper.setTimeZone(TimeZone.getTimeZone("UTC"));
//mapper.configure(DeserializationFeature.READ_DATE_TIMESTAMPS_AS_NANOSECONDS,true);
//mapper.configure(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS,true);
mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSSSS"));
//Serialization - saving the created objects in the sequence of bytes.
mapper.writeValue(new File("c:\\temp\\user.json"), user);
System.out.println("Serialized Outcome = " + mapper.writeValueAsString(user));
//Deserialization - Retrieving those saved bytes into the form of original object.
user = mapper.readValue(new File("c:\\temp\\user.json"), User.class);
System.out.println("Deserialized Outcome = " + user);
} catch (IOException e) {
e.printStackTrace();
}
}
}
// pom (only relevant part)
<properties>
<java-version>1.6</java-version>
<jackson.databind-version>2.2.3</jackson.databind-version>
</properties>
<dependencies>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.databind-version}</version>
</dependency>
// console
firstTryValue = 2015-01-08 11:31:53.000773
secondTryValue = 2015-01-08 11:31:53.000773
Serialized Outcome = {"tsFirstTry":"2015-01-08 17:31:53.000000","tsSecondTry":"2015-01-08 11:31:53.000000"}
Deserialized Outcome = User [tsFirstTry=2015-01-08 11:31:53.0, tsSecondTry=2015-01-08 11:31:53.0]
source to share
Yes, you can use Jackson's nanosecond value; to save nanoseconds in Java 8 you can use java.util.Date
or java.sql.Timestamp
(if you haven't disabled the Jackson setting DeserializationFeature.READ_DATE_TIMESTAMPS_AS_NANOSECONDS
and SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS
which are enabled by default).
Before Java 8, you can use java.math.BigDecimal
to store the number of days from a given time and fractional time of day. Or, just store the value in String representation. Java 7 and earlier do not store nanoseconds in dates, only milliseconds. Therefore, if you convert a value to, java.util.Date
or one of its subclasses, for example java.sql.Timestamp
, you will only have millisecond precision. So java.text.DateFormat
it won't come in handy here if you are using it to convert to any kind of java Date in pre-Java 8 environment.
Here is another discussion of nanoseconds in java Timestamps: java.sql.Timestamp way to store NanoSeconds
source to share