In spring boot rest controller how is a Date field mapped. Let us say we send in json {"receivedDate":"2024-05-15","num1":5}
. How will it be mapped to a field in Java object having a property private Date receivedDate; (assuming java.util.Date)
we can consider, a simple class
public class SampleClass {
Integer num1;
Date receivedDate;
//getters and setters
}
and a Rest Controller in Spring Boot app,
public ResponseEntity getDetails(@RequestBody SampleClass sampleClass) {
try {
System.out.println("Execution of getDetails started. received date is: "+sampleClass.getReceivedDate());
...............}
....
}
I get result in my console as(I executed this api at 10:20 Am IST):
Execution of getDetails started. received date is: Thu May 16 05:30:00 IST 2024
So, the result contains 05:30:00 and not my present time. What if I wanted it to be just 00:00:00.0 instead of 05:30:00.0. I am confused because in some stackoverflow answers, I came to know that Jackson's default behaviour is to do as per UTC. But it is doing as per IST though I have no configuration done.
Jackson converts correctly, the root problem is that you use an outdated, legacy class, known for the issues it's causing.
This has been asked countless times in different forms. Do not use java.util.Date
, it is not actually a date, it is an instant since the epoch, the class is broken, misleading, causes many programmer errors, the API is deprecated for a reason.
In addition, toString()
, which you use implicitly when printing, silently applies the default timezone when formatting the output, adding to the confusion. Your format is actually a simple date, without a time component, use java.time.LocalDate
instead, part of java.time
, the modern java date-time API, available since java 8.
@Data
public class SampleClass {
private Integer num1;
private LocalDate receivedDate;
}
If you need to conform to another API, which requires java.util.Date
, there are convenient methods to make the conversion correctly.
Instant instantStartOfDay = sampleClass.getReceivedDate()
.atStartOfDay()
.toInstant(ZoneOffset.UTC);
Date asDate = Date.from(instantStartOfDay);