Below is my list of json objects:
[
{
"Date": "2022-04-06T00:00:00"
},
{
"Date": "2022-12-06T00:00:00"
}
]
and my POJO:
@Data
public class MyPojo {
@JsonProperty("Date")
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-mm-dd")
private Date date;
}
Deserialization code:
public <T> List<T> toObjList(String json, Class<T> className) {
try {
return new ObjectMapper().readValue(json, objectMapper.getTypeFactory().constructCollectionType(List.class, className));
} catch (Exception ex) {
log.error("Exception converting json to Object: {}", json);
throw new AppException("Exception while converting String to Object list", ex, HttpStatus.INTERNAL_SERVER_ERROR);
}
}
My problem is, despite omitting the time in jsonFormat
pattern, I see that some random time is added to each date. I printed the serialized dates and following was the output:
(date=Fri Sep 30 05:30:00 IST 2022)
I tried parsing a date with simleDateFormat and it seemed to parse excluding the time.
String input = "2022-09-30T00:00:00";
SimpleDateFormat parser = new SimpleDateFormat("yyyy-MM-dd");
Date date = parser.parse(input);
System.out.println(date);
This gave an expected output
Fri Sep 30 00:00:00 IST 2022
CodePudding user response:
Avoid legacy date-time classes
The terrible java.util.Date
class was years ago supplanted by the modern java.time classes defined in JSR 310.
Among the many flaws in that class, the name Date
is a misnomer. The class represents a moment as seen with an offset of zero hours-minutes-seconds from UTC. So it always has a time of day, plus the offset of zero.
java.time.LocalDate
If you want to represent a date-only value, without time of day, and without offset or time zone, use the modern class java.time.LocalDate
.
Determining a date from a moment
If you want to get a date from an existing java.util.Date
object, immediately convert to its modern replacement, java.time.Instant
. Use the new conversion methods added to the old classes.
Instant instant = myJavaUtilDate.toInstant() ;
To determine a date, you must specify a time zone. For any given moment, the date varies around the globe by time zone. “Tomorrow” in Asia/Tokyo
is simultaneously “yesterday” in America/Edmonton
.
ZoneId z = ZoneId.of( "Africa/Tunis" ) ; // Specify your time zone of interest.
ZonedDateTime zdt = instant.atZone( z ) ;
Extract your desired date-only value.
LocalDate ld = zdt.toLocalDate() ;
Compare LocalDate
objects using isEqual
, isBefore
, and isAfter
methods.
Search to learn more. All this has been covered many times on Stack Overflow.
CodePudding user response:
The root cause of the problem is using m
instead of M
in pattern = "yyyy-mm-dd"
. The letter M
stands for Month in year while m
stands for Minute in hour.
Note that the java.util
Date-Time API and their parsing/formatting API, SimpleDateFormat
are outdated and error-prone. It is recommended to stop using them completely and switch to the modern Date-Time API. Learn about the modern date-time API from Trail: Date Time.