Instant, Duration and Period in Java

Instant marks a point on the timeline; Duration measures time based amounts and Period measures date based ones.

Instant

An Instant is a single point on the timeline, counted in seconds and nanoseconds from the epoch of 1 January 1970 UTC. It carries no zone and no calendar, which makes it the correct type for a timestamp.

Instant now = Instant.now();
Instant epoch = Instant.EPOCH;
Instant parsed = Instant.parse("2026-08-21T09:30:00Z");
Instant fromMillis = Instant.ofEpochMilli(1_755_000_000_000L);

System.out.println(now.toEpochMilli());
System.out.println(now.getEpochSecond());
System.out.println(now.isBefore(parsed));
Use Instant for anything recorded, compared or stored: created timestamps, audit logs, cache expiry. Convert to a zoned type only when a human has to read it.

Duration

A Duration is a time based amount, measured in seconds and nanoseconds. It suits hours, minutes and seconds.

Duration twoHours = Duration.ofHours(2);
Duration ninetySeconds = Duration.ofSeconds(90);
Duration fromText = Duration.parse("PT1H30M");        // ISO 8601 form

System.out.println(twoHours.toMinutes());             // 120
System.out.println(ninetySeconds.toSecondsPart());    // 30
System.out.println(twoHours.plusMinutes(30));         // PT2H30M

Duration between = Duration.between(
        LocalTime.of(9, 0), LocalTime.of(17, 30));    // PT8H30M

Period

A Period is a date based amount, measured in years, months and days. It respects the calendar, so a month is a real month rather than 30 days.

Period oneMonth = Period.ofMonths(1);
Period mixed = Period.of(1, 2, 15);          // 1 year, 2 months, 15 days
Period parsed = Period.parse("P1Y2M15D");

Period age = Period.between(LocalDate.of(1998, 3, 12), LocalDate.now());
System.out.printf("%d years, %d months, %d days%n",
        age.getYears(), age.getMonths(), age.getDays());

Duration compared with Period

DurationPeriod
MeasuresSeconds and nanosecondsYears, months, days
Works withInstant, LocalTime, LocalDateTimeLocalDate
Calendar awareNoYes
A day meansExactly 86400 secondsOne calendar day
ZonedDateTime before = ZonedDateTime.of(
        LocalDateTime.of(2026, 3, 28, 12, 0), ZoneId.of("Europe/London"));

ZonedDateTime plusDuration = before.plus(Duration.ofDays(1));   // exactly 24 hours
ZonedDateTime plusPeriod = before.plus(Period.ofDays(1));       // the same clock time

Across a daylight saving change these give different answers. Duration adds 24 hours of elapsed time; Period adds one calendar day and keeps the local time. Choosing wrongly produces bugs that appear twice a year.

ChronoUnit for a single number

LocalDate start = LocalDate.of(2026, 1, 1);
LocalDate end = LocalDate.of(2026, 8, 21);

System.out.println(ChronoUnit.DAYS.between(start, end));     // 232
System.out.println(ChronoUnit.MONTHS.between(start, end));   // 7
System.out.println(ChronoUnit.WEEKS.between(start, end));    // 33

Instant from = Instant.now();
Instant to = from.plusSeconds(3725);
System.out.println(ChronoUnit.MINUTES.between(from, to));    // 62

Use Period when you want the parts broken down, and ChronoUnit when you want one total.

Measuring elapsed time

Instant start = Instant.now();
doWork();
Duration taken = Duration.between(start, Instant.now());
System.out.println("Took " + taken.toMillis() + " ms");
// For precise measurement, prefer the monotonic clock
long start = System.nanoTime();
doWork();
long tookMs = (System.nanoTime() - start) / 1_000_000;

Instant.now() reads the wall clock, which can jump if the system time is adjusted. System.nanoTime() is monotonic and is the right tool for measuring elapsed time.

Converting between types

Instant instant = Instant.now();

ZonedDateTime zoned = instant.atZone(ZoneId.of("Asia/Kolkata"));
LocalDateTime local = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
LocalDate date = instant.atZone(ZoneId.systemDefault()).toLocalDate();

Instant back = local.atZone(ZoneId.systemDefault()).toInstant();
Instant fromDate = date.atStartOfDay(ZoneId.systemDefault()).toInstant();

An Instant needs a zone to become a local date or time, and a local value needs a zone to become an Instant. That requirement is deliberate: it forces the ambiguity to be resolved explicitly.

A practical example

public record CacheEntry<T>(T value, Instant storedAt, Duration timeToLive) {

    public boolean isExpired(Instant now) {
        return now.isAfter(storedAt.plus(timeToLive));
    }

    public Duration remaining(Instant now) {
        Duration left = Duration.between(now, storedAt.plus(timeToLive));
        return left.isNegative() ? Duration.ZERO : left;
    }
}

Common mistakes

  • Using Duration.ofDays(30) where a calendar month was meant.
  • Measuring elapsed time with System.currentTimeMillis(), which is not monotonic.
  • Expecting Period.between to give a total number of days; it gives years, months and days.
  • Storing a LocalDateTime as a timestamp and losing the zone information.
  • Adding a Duration across a daylight saving boundary and getting an unexpected local time.

Best practices

  • Store and compare timestamps as Instant or UTC.
  • Use Duration for hours and below, Period for days and above.
  • Use ChronoUnit when a single total is wanted.
  • Use System.nanoTime() for measuring, never the wall clock.
  • Be explicit about the zone whenever converting.

Practice

  1. Compute someone age in years, months and days from a birth date.
  2. Explain when Duration.ofDays(1) and Period.ofDays(1) give different results.
  3. Write a cache entry type that expires after a configurable duration.
  4. Why is System.nanoTime() preferred over Instant.now() for timing a method?
  5. Convert an Instant to a LocalDate in a named zone and explain why the zone is required.

Conclusion

Instant marks when something happened, Duration measures elapsed time, and Period measures calendar amounts. Pick by whether the calendar matters, and be explicit about zones at every conversion.

Written by Lorens Mishra

Default administrator account created by the installer.

Continue reading

All Java notes →
Java

Introduction to Java

Java is a statically typed, object oriented language that compiles to bytecode and runs on a virtual machine, which is what makes it portable.

Read more

Discussion

0 comments
Sign in to join the discussion.

No comments yet. Be the first to say something.