Java
Completed
-
Section 1: Getting Started
-
Section 2: Core Syntax
-
Section 3: Object-Oriented Java
-
Section 4: Collections Framework
-
Section 5: Exception Handling
-
Section 6: Generics
-
Section 7: Functional Java
-
Section 8: Concurrency
-
Section 9: I/O and NIO
-
Section 10: JVM Internals
-
Section 11: Modern Java Features
-
Section 12: Build Tools and Project Structure
-
Section 13: Testing
-
Section 14: Databases and Persistence
-
Section 15: Networking
-
Section 16: Design and Best Practices
-
Section 17: Reflection and Annotations
-
Section 18: Logging and Diagnostics
-
Section 19: Date, Time, and Internationalization
-
Section 20: Java Platform Module System
-
Section 21: Security in Java
-
Section 22: Advanced Collections and Data Structures
-
Section 23: More Concurrency Patterns
-
Section 24: Compression, Files, and System Integration
-
Section 25: GUI Programming
-
Section 26: Practical Projects
-
Section 27: Data Structures and Algorithms
-
Section 28: Interview and Algorithm Practice
-
Section 29: JSON and Data Interchange
-
Section 30: More Concurrency Utilities
-
Section 31: More Collections and Streams Practice
-
Section 32: More File and System Programming
-
Section 33: Standard Library Deep Dive
-
Section 34: More Practice and Drills
-
Section 35: More Testing and Quality
-
Section 36: More Design Patterns and Architecture
-
Section 37: Career and Ecosystem
-
Section 38: More OOP and Architecture Practice
-
Section 39: More Enterprise Concepts
-
Section 40: Advanced JavaFX
-
Section 41: More Interview Practice
178: Working with Duration and Period
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 aPeriodrepresenting the time left until expiry. - Create a method
isWithinGracePeriod(Instant expiryInstant, Instant now)that returns aboolean. A user is in the grace period if the current time is within 48 hours (aDuration) after the expiry instant. - In your
mainmethod, test a scenario where a user's subscription expired 24 hours ago to ensure the grace period logic works correctly.
There are no comments for now.