22

I don't really understand TemporalAdjusters or Java's new time library even after reading numerous tutorials.

How can I convert an Instant object to a LocalTime object. I was thinking something along the lines of the following:

LocalTime time = LocalTime.of(
    instantStart.get(ChronoField.HOUR_OF_DAY),
    instantStart.get(ChronoField.MINUTE_OF_HOUR)
);

But it isn't working. How can I do this?

Paco
  • 81
  • 1
  • 9
Connorelsea
  • 2,308
  • 6
  • 26
  • 47
  • 1
    There is a handy conversion chart in this answer to a related question: https://stackoverflow.com/a/36639155/292728 – Kevin K Mar 17 '21 at 22:06

3 Answers3

33

The way I understand it... Instant is a UTC style time, agnostic of zone always UTC. LocalTime is a time independent of given zone. So you'd expect the following would work given that Instant implements TemporalAccessor,

Instant instant = Instant.now();
LocalTime local =  LocalTime.from(instant);

but you get "Unable to obtain LocalTime from TemporalAccessor" error. Instead you need to state where "local" is. There is no default - probably a good thing.

Instant instant = Instant.now();
LocalTime local =  LocalTime.from(instant.atZone(ZoneId.of("GMT+3")));
System.out.println(String.format("%s => %s", instant, local));

Output

2014-12-07T07:52:43.900Z => 10:52:43.900

instantStart.get(ChronoField.HOUR_OF_DAY) throws an error because it does not conceptually support it, you can only access HOUR_OF_DAY etc. via a LocalTime instance.

Adam
  • 35,919
  • 9
  • 100
  • 137
  • Ah. Well then I was misunderstanding a lot about the classes themselves. I am trying to store the start and end time of an event in a calendar as two instances. then make a duration from those instances. What should I do instead? How should I go about storing that information using the Java 8 Time classes. And also I am not sure I understand Temporal Accessors from the explanation given by the Oracle tutorials. Where could I go to learn that in a better fashion? – Connorelsea Dec 07 '14 at 07:54
  • 3
    @Connorelsea I'm not an expert, I find the new java.time API incredibly confusing too. I'd think storing instants would be better and only use LocalTime for when you actually need to display to the user (in a given time zone). – Adam Dec 07 '14 at 08:19
  • Actually, LocalTime does not include a time zone. Its javadoc states: "This class does not store or represent a date or time-zone. Instead, it is a description of the local time as seen on a wall clock." Afaik, an Instant has no concept like hour of the day, but only seconds since the epoch. That's why you first have to create a ZonedDateTime from that instant. – Alex Mar 02 '17 at 13:40
  • LocalTime is not associated with a timezone! Please remove this misleading statement from your answer. It is a simple representation of time for use cases where you do not need to consider timezones. – Malcolm Smith Mar 17 '21 at 15:45
  • 2
    The classes are just about completely different things. `Instant` is a moment in time. A snapshot, for example the moment the second world war ended. It is not really talking about times or dates specifically, it is just a snapshot of a moment. `LocalTime` is about the concept of time. For example if I am saying _"I like to get up at 8 am"_, this has nothing to do with the actual time of a day or anything. Similar for `LocalDate`, when I am saying that christmas is at the 25th December. It is just about the concept of dates, not about real dates. – Zabuzard Mar 17 '21 at 21:49
  • That said, getting the time of an `Instant` makes no sense, it is lacking the information of _where_. The moment second world war ended was a completely different time and also date for people all over the world. So the correct way would be to apply a zone to the `Instant` first to get a `ZonedDateTime` and then to extract the time information to construct a `LocalTime` object, if that is really necessary (to me it smells like `LocalTime` is used incorrectly here in the first place). – Zabuzard Mar 17 '21 at 21:53
  • Regarding calendars, no, do *not* use `Instant`. A future appointment at say 3 PM may not land on the same moment as it does now after politicians change the rules of the time zone(s) under their jurisdiction. And change the rules they will, with surprising frequency, around the world. If you use `Instant`, that 3 PM appointment will later appear as something like 2 PM. I have already posted on this extensively. Search for my name and the words appointment, LocalDateTime, ZoneId, ZonedDateTime. – Basil Bourque May 01 '22 at 16:39
0

yourInstant.atZone(yourZoneId).toLocalTime()

Eva
  • 4,397
  • 5
  • 43
  • 65
0

Instead of hardcoding the timezone you could use the configured timezone of your system:

LocalTime.ofInstant(instant, ZoneId.systemDefault())
IPP Nerd
  • 992
  • 9
  • 25