Skip to Content
Course content

178: Working with Duration and Period

Click on the "Edit" button in the top corner of the screen to edit your slide content.

Imagine you're organizing two different kinds of events. First, you're timing a 100-meter sprint. You use a stopwatch because you care about the exact number of seconds and milliseconds that pass. Second, you're planning a wedding anniversary party. You don't use a stopwatch for that; you use a calendar. You think in terms of "three years and two months from now."

In Java, we have two distinct classes for these two ways of thinking: Duration and Period. If you try to use one where the other belongs, you'll either get a compiler error or, worse, a bug that only appears during a leap year. Here is how they map to that analogy:

  • Duration is your stopwatch. It measures "machine time"—exact nanoseconds, seconds, and minutes.
  • Period is your calendar. It measures "human time"—years, months, and days.

Measuring Precise Elapsed Time with Duration

I usually reach for java.time.Duration when I'm dealing with Instant or LocalTime. It's perfect for things like API timeouts, cache expiration, or calculating how long a process took to run. The key is that a Duration is a fixed amount of time, regardless of the date.

import java.time.Duration;
import java.time.Instant;

public class DurationExample {
    public static void main(String[] args) {
        Instant start = Instant.now();
        
        // Simulate some heavy work
        try { Thread.sleep(1500); } catch (InterruptedException e) {}
        
        Instant end = Instant.now();
        
        Duration timeElapsed = Duration.between(start, end);
        System.out.println("Process took: " + timeElapsed.toMillis() + " milliseconds");
        
        // You can also create specific durations easily
        Duration timeout = Duration.ofSeconds(30);
        System.out.println("Timeout set to: " + timeout.toMinutes() + " minutes");
    }
}

Handling Calendar-Based Gaps with Period

Now, if you're working with LocalDate, you want java.time.Period. Why not just use seconds? Because humans are messy. A "month" isn't a fixed number of seconds—February is shorter than March. A "year" might be 365 or 366 days. Period handles this conceptual "calendar distance" for us.

import java.time.LocalDate;
import java.time.Period;

public class PeriodExample {
    public static void main(String[] args) {
        LocalDate birthday = LocalDate.of(1995, 5, 15);
        LocalDate today = LocalDate.now();
        
        Period age = Period.between(birthday, today);
        
        System.out.println("You are " + age.getYears() + " years, " 
                           + age.getMonths() + " months, and " 
                           + age.getDays() + " days old.");
        
        // Adding a period to a date
        LocalDate nextRenewal = today.plus(Period.ofMonths(6));
        System.out.println("Next billing cycle: " + nextRenewal);
    }
}

Why You Can't Mix These Two

One thing that trips people up is trying to find the "Duration" of a "Period." You'll notice that Period doesn't have a toSeconds() method. That's intentional. Because a Period of "one month" is ambiguous—is it 28 days or 31? Java refuses to guess for you.

I've seen developers try to calculate a user's age by converting the birthday to epoch milliseconds and dividing by a magic number like 31,536,000,000 (milliseconds in a year). Please, don't do that. That's how you end up with "off-by-one" bugs during leap years. Use Period for dates and Duration for timestamps.




📋 Practical Task

Exercise: Subscription Renewal Calculator

You are building a subscription management system for a SaaS product. You need to create a class that calculates the remaining time for a user's subscription and determines if they are in a "grace period."

Requirements:

  • Create a method calculateRemainingTime(LocalDate startDate, LocalDate expiryDate, LocalDate today) that returns a Period representing the time left until expiry.
  • Create a method isWithinGracePeriod(Instant expiryInstant, Instant now) that returns a boolean. A user is in the grace period if the current time is within 48 hours (a Duration) after the expiry instant.
  • In your main method, test a scenario where a user's subscription expired 24 hours ago to ensure the grace period logic works correctly.
Rating
0 0

There are no comments for now.

to be the first to leave a comment.