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]

      

+3


source to share


1 answer


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

+6


source







All Articles