Instant in Java: the java.time.Instant Class Explained - Quiz

Total: 6 questions

1. 

What is an Instant in Java, and why does Instant.now() show a different time than the local clock?

java.time.Instant (Java 8+) is an immutable, thread-safe class that represents a single point on the UTC time-line. Internally it holds the seconds since the epoch 1970-01-01T00:00:00Z (a long) and the nanoseconds within that second (an int from 0 to 999,999,999). It has no day, month, year or time zone.

Instant.now() returns the current moment from the system clock in UTC and does not depend on the JVM time zone, and toString() always prints it in UTC with the Z suffix:

System.out.println(Instant.now());       // 2026-10-19T11:35:07.123456Z
System.out.println(LocalDateTime.now()); // 2026-10-19T07:35:07.123512 (JVM zone America/New_York)

This is not a bug, just another way of writing the same moment. To show the time to a user, move the moment into a zone: instant.atZone(zone) or a formatter with withZone(). An Instant is not created with a constructor (there is none) but with the factory methods now(), ofEpochSecond(), ofEpochMilli() and parse().

2. 

Which values can you get from an Instant, and how does instant.get(ChronoField.MILLI_OF_SECOND) differ from instant.toEpochMilli()?

Only values tied to the epoch: getEpochSecond() returns the seconds (long), getNano() the nanoseconds within the second (int), toEpochMilli() the milliseconds since the epoch. The generic get() and getLong() support the fields NANO_OF_SECOND, MICRO_OF_SECOND and MILLI_OF_SECOND; getLong() also supports INSTANT_SECONDS.

Instant instant = Instant.parse("2024-03-15T10:30:45.123456789Z");
instant.get(ChronoField.MILLI_OF_SECOND); // 123 (within the second)
instant.toEpochMilli();                   // 1710498645123 (since the epoch)

MILLI_OF_SECOND is 0–999 within the current second, while toEpochMilli() is all the milliseconds since 1970 (nanoseconds beyond the millisecond are dropped). There are no date or time-of-day fields: instant.get(ChronoField.HOUR_OF_DAY) throws UnsupportedTemporalTypeException: Unsupported field: HourOfDay. To find out the hour or the day, move the moment into a zone with atZone().

3. 

How do you compare two Instant objects?

With isAfter(), isBefore() and equals(), which return a boolean. For sorting there is compareTo(): Instant implements Comparable<Instant>. The seconds are compared first, then the nanoseconds if the seconds are equal; the time zone plays no role because there is none.

Instant now = Instant.now();
Instant fiveSecondsAfterEpoch = Instant.ofEpochSecond(5);
now.isAfter(fiveSecondsAfterEpoch);             // true
now.compareTo(fiveSecondsAfterEpoch) > 0;      // true

Compare the result of compareTo() with zero, not with 1 or -1: when the seconds are equal, the method returns the difference in nanoseconds. Unlike LocalDate, Instant has no isEqual() method — use equals(). The same moment written in different zones (03:30 in New York and 07:30 in UTC on March 15, 2024) gives equal Instant values after toInstant().

4. 

Which strings can Instant.parse() handle, and how do you parse a string with an offset such as 2024-03-15T03:30:00-04:00?

Instant.parse() accepts only the ISO format (DateTimeFormatter.ISO_INSTANT) with UTC specified. Strings without a zone are not parsed in any Java version:

Instant.parse("2024-03-15T07:30:00Z");      // 2024-03-15T07:30:00Z
Instant.parse("2024-03-15T07:30:00");       // DateTimeParseException ... at index 19
Instant.parse("2024-03-15");                // DateTimeParseException ... at index 10
Instant.parse("2024-03-15T03:30:00-04:00"); // Java 12+: 2024-03-15T07:30:00Z; Java 8-11: DateTimeParseException

An offset instead of Z is supported only since Java 12 (JDK-8166138). If your code must also run on Java 8, parse such strings with OffsetDateTime.parse(text).toInstant(). A string without a zone is turned into an Instant with LocalDateTime.parse(s).atZone(zone).toInstant(), and a string in a custom format with ZonedDateTime.parse(text, formatterWithZone).toInstant().

5. 

How do you convert an Instant to ZonedDateTime, LocalDateTime and java.util.Date, and back?

To get the date and time «on the clock», you have to specify a time zone:

Instant instant = Instant.parse("2024-03-15T07:30:00Z");
ZonedDateTime newYork = instant.atZone(ZoneId.of("America/New_York"));          // 2024-03-15T03:30-04:00[America/New_York]
OffsetDateTime minus4 = instant.atOffset(ZoneOffset.ofHours(-4));                // 2024-03-15T03:30-04:00
LocalDateTime tokyo = LocalDateTime.ofInstant(instant, ZoneId.of("Asia/Tokyo")); // 2024-03-15T16:30
Date legacy = Date.from(instant);
Instant back = legacy.toInstant();

The way back to Instant is toInstant() (on ZonedDateTime, OffsetDateTime and Date). There is one moment, only the reading on the clock changes: 03:30 in New York, 16:30 in Tokyo. LocalDate.ofInstant() appeared in Java 9; in Java 8 you write instant.atZone(zone).toLocalDate(). Converting to Date reduces precision to milliseconds, so the nanoseconds are lost.

6. 

What does Instant.truncatedTo() do, and why doesn't truncatedTo(ChronoUnit.DAYS) give the start of the day in local time?

truncatedTo(unit) returns a new Instant with everything smaller than the given unit dropped:

Instant t = Instant.parse("2024-01-31T09:30:00Z");
System.out.println(t.truncatedTo(ChronoUnit.HOURS)); // 2024-01-31T09:00:00Z

An Instant knows no time zone, so truncatedTo(ChronoUnit.DAYS) gives midnight in UTC — in New York in summer that is 8 PM of the previous day, not 00:00. The start of the day in local time is computed through the zone: LocalDate.now(zone).atStartOfDay(zone).toInstant().

Page 1 of 1