I have an angular/spring boot application, on client side I'm using a primeng calendar input component, which takes the local date and converts it to UTC zoned date-time. I then send this date to a REST Controller and it's deserialized using LocalDateTimeDeserializer
. The problem is, it just takes the date as-is, without actually caring about the server time-zone (so UTC datetime becomes local datetime).
I looked into the source code and here's the responsible snippet:
if (string.endsWith("Z")) {
return LocalDateTime.ofInstant(Instant.parse(string), ZoneOffset.UTC);
}
Shouldn't it be:
if (string.endsWith("Z")) {
return LocalDateTime.ofInstant(Instant.parse(string), ZoneOffset.of(ZoneId.systemDefault().getId()));
}
Or something similar?
Or is there something I'm not getting about the whole concept of LocalDateTime/Timezones?
No, it's doing the right thing IMO.
A LocalDateTime
isn't "local to the server", it's "not in any specific time zone". If you've got a text value which indicates a date/time and any sort of time zone indicator (e.g. an offset from UTC or a time zone ID) then the most appropriate conversion to LocalDateTime
would be to just ignore the offset/ID. So for example, take:
2017-07-18T12:04:00+01:00
That's a LocalDateTime
of 2017-07-18T12:04:00, with a UTC offset of +1. So I'd expect that parsing it to a LocalDateTime
, would give a result of 2017-07-18T12:04:00.
I would personally try not to this to start with though: parse the textual data into the most appropriate kind of value, then change to a different kind of value in whatever way you want. So if your input text always does have a UTC offset (potentially using Z
for 0), then parse it as an OffsetDateTime
, then you decide how you want to convert that to a LocalDateTime
, and your code will be much clearer.
Basically, separate "change representation from text to in-memory" and "change what's being represented" into distinct operations.
See more on this question at Stackoverflow