1

I have a private java.sql.Timestamp myDate in some model (POJO) class like below

private String isActive;
private Date dob;
private Timestamp createdDate;
private Timestamp lastMktPrefUpdateAt;

We were using spring boot version to 1.5.10.RELEASE and REST API response for timestamp field was in millisecond format like below -

   {
        "isActive": "y",
        "lastMktPrefUpdateAt": 1632195609787,
        "dob": "08/12/1991",
        "createdDate": 1632195609788
    }

We have recently upgraded the spring boot version to 2.3.0.RELEASE and this started sending timestamp field in response to some ISO format like below -

  {
        "isActive": "y",
        "lastMktPrefUpdateAt": "2021-09-20T22:10:09.787+0000",
        "dob": "07/12/1991",
        "createdDate": "2021-09-20T22:10:09.788+0000"
    }

Can someone please help answering, how can we format Timestamp back to millisecond format? We need to format Timestamp at global level meaning without changing all the POJO classes.

2 Answers2

3

Try this in your properties file

spring.jackson.serialization.write-dates-as-timestamps:true

OR
Use @JsonFormat(shape = JsonFormat.Shape.NUMBER) above the property that you want.

Update

If you want to add millis to your timestamp, try to pass the long value to the Timestamp constructor and call the getTime() method to receive a 13-digits timestamp.

   long now = System.currentTimeMillis();
   Timestamp timeStamp= new Timestamp(now);
   System.out.println(timeStamp.getTime());
Faramarz Afzali
  • 726
  • 1
  • 10
  • 24
  • This is giving the expected result except the millis value is coming as current time - 5:30 hrs. I tried to set spring.jackson.time-zone: GMT+05:30 but seems like it's returning the same value. Can you please help here? – user3250123 Sep 21 '21 at 13:34
  • Could you change the type of `Timestamp` to Date and try again? Because I tried with Date and it returns 13-digits timestamp's standard. `@JsonFormat(shape = JsonFormat.Shape.NUMBER) private Date createdDate; ` – Faramarz Afzali Sep 21 '21 at 17:45
  • However, I update the answer, I hope your problem will be fixed. – Faramarz Afzali Sep 21 '21 at 18:02
0

You could convert that string to a ZonedDateTime object which has a .toInstant().toEpochMilli() method.

Something like: long millis = ZonedDateTime.of(LocalDateTime.parse(str), ZoneId.of("Etc/UTC")).toInstant().toEpochMilli();

see:

How to get milliseconds from LocalDateTime in Java 8

https://docs.oracle.com/javase/8/docs/api/java/time/LocalDateTime.html

https://docs.oracle.com/javase/8/docs/api/java/time/ZonedDateTime.html

However, I would recommend refactoring the system to use the immutable LocalDatTime object at a later point.

(There may be an appropriate annotation you can put on that timestamp field to parse it in a specific way, but not one that I am aware of.)

MrOtto
  • 25
  • 1
  • 8
  • This will require a change to put at POJO level but we have many such POJO's and looking for a solution which can be added at global level. – user3250123 Sep 21 '21 at 10:23
  • @user3250123 initially you can use that .toEpochMillis() to assign the millis value for the POJO. (the ZonedDateTime object is only used to parse the input string, it doesn't need to be saved). – MrOtto Sep 21 '21 at 11:19
  • the difference comes from how a Timestamp object is now being parsed, it sounds like you want that field to be a long. The return type wants to be used like a LocalDateTime. – MrOtto Sep 21 '21 at 11:26
  • correct, I am looking for some solution where I need not to touch the POJO classes. Because this will require a change at consumer end which we can not afford. Earlier field was of type Timestamp and value was going in millisecond. – user3250123 Sep 21 '21 at 11:36