From the front end I am receiving a separate LocalDate
(variable name is date
), along with separate Integers for hours, minutes, seconds, and an "AM" or "PM" String, and I need to combine these into a java.time.Instant
object to store in the database. I tried to construct a LocalTime
as follows, adding 12 hours if this is a PM time and then constructing an Instant
:
LocalTime time = LocalTime.of("pm".equals(amPm) ? hours + 12: hours, minutes, seconds);
Instant instant = date.atTime(time).toInstant(ZoneOffset.UTC);
But when I store and reload the page, though the date is always intact, the time is always being changed. If I set the date to 1/29/1900 and the time to 07:01:01 AM, the Instant
I am creating and storing has the value: 1900-01-29T07:01:01Z when I debug, which appears correct, but when the page reloads, the time says 02:01:01 AM, and that is the time that is stored in the database.
Am I constructing the time or the instant incorrectly?
There’s hardly any doubt that your unexpected observations are due to one or more time zone issues.
So the first thing you need to do is make sure you know which time zones are involved.
Once you know this you can check:
Instant
of1900-01-29T07:01:01Z
correct? TheInstant
displays its time in UTC (denoted by the trailingZ
).Instant
to 02:01:01 AM in the database time zone correct?To answer your question:
It depends; it’s certainly possible.
pm
is always in lower case and that 12 o’clock (midnight or noon) is given as 0. On one hand I find both assumptions more or less unlikely, on the other hand they cannot account for the discrepancy of 5 hours that you observed. 12 would conventionally be given as 12 (not 0) on a 12 hour clock. And your question givesPM
in upper case.Instant
assumes that the front end sent the time in UTC. To me this sounds unlikely too, and it may be the reason or one of the reasons why you observed an incorrect time being displayed back after page reoload.Code example
In the following snippet I am making the opposite assumptions: 12 is given as 12, AM/PM may be in any case, and the front end time zone is America/New_York. It’s probably way off, but there may be a detail that you can pick and use for your purpose.
Output is:
Geeky section: avoiding formatting time into a string and parsing it back
I couldn’t help thinking about whether it would be possible to have java.time parse the AM/PM string without having to construct a string for the time of day and parse it. It is possible, but we need to use the low-level
TemporalAccessor
interface, which is otherwise usually unnecessary.Construction of the
Instant
proceeds as before.