Reputation: 715
I have a SpringBoot 2.6.14 web-app with JPA 2.2 and Hibernate 5.
Now I have a String with this format
"2024-03-04T14:10:37.000Z"
And, following some instruction (googling around) I write the following String to LocalData converter:
default LocalDate stringToDate(String data) {
if (data == null || data.isEmpty()) return null;
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
formatter = formatter.withLocale(Locale.getDefault());
return LocalDate.parse(data, formatter);
}
The parsing works but the result is 2024-03-04, the hour, minutes and seconds are truncated. What's wrong?
Upvotes: 0
Views: 57
Reputation: 338564
Z
. That discards vital information.Instant
.parse( "2024-03-04T14:10:37.000Z" )
.atZone( ZoneId.of( "America/Edmonton" ) )
.toLocalDate()
Or:
LocalDate
.ofInstant (
Instant.parse( "2024-03-04T14:10:37.000Z" ) ,
ZoneId.of( "America/Edmonton" )
)
LocalDateTime
Both Answers recommending the LocalDateTime
classes are wrong.
That class represents a date with a time-of-day. But your string input contains a third component: offset from the temporal meridian, UTC.
Your input represents a moment, a specific point on the timeline. But the LocalDateTime
object cannot represent a moment.
A LocalDateTime
object is inherently ambiguous. If we had a LocalDateTime object for noon on January 23rd of 2024, we have no way of knowing if that means noon in Tokyo Japan 🇯🇵, noon in Toulouse France 🇫🇷, or noon in Toledo Ohio US 🇺🇸 — three different moments several hours apart.
Instant
The Z
on the end indicates on offset of zero hours-minutes-seconds from UTC. This abbreviation of +00:00
is defined in the ISO 8601 standard.
Parse your input as a Instant
object to represent a moment, a specific point on the timeline.
Instant instant = Instant.parse( "2024-03-04T14:10:37.000Z" ) ;
LocalDate
To get a date from a moment, you must specify a time zone. For any given moment, the date varies around the globe by time zone. A single moment can simultaneously be “tomorrow” in Tokyo while also “yesterday” in Toledo.
Define the time zone through which you want to view the date.
ZoneId z = ZoneId.of( "America/Edmonton" ) ;
Apply that zone to our instant to produce a ZonedDateTime
.
ZonedDateTime zdt = instant.atZone( z ) ;
Both the Instant
object and the ZonedDateTime
object represent the very same moment, the same point on the timeline.
Extract the date portion.
LocalDate ld = zdt.toLocalDate() ;
Upvotes: 2
Reputation: 89234
LocalDate
, as the name suggests, does not include a time. Consider using LocalDateTime
instead.
return LocalDateTime.parse(data, formatter);
Upvotes: 2