- List out Java 8 Date/Time API - Practical Formulas & Methods (Included this question to make the preparation easy)
- What is Java 8 Date/Time API? Why better than old Date/Calendar?
- Key classes: LocalDate, LocalTime, LocalDateTime, ZonedDateTime, Instant.
- Common operations: plus/minus, Period, Duration, formatting/parsing.
- Time zones and ZoneId — examples.
- Difference between Period and Duration.
- How to handle legacy Date with new API (toInstant, from).
- Best practices for Date/Time in production (immutability, thread-safety).
List out Java 8 Date/Time API - Practical Formulas & Methods
Organized the Java 8 Date/Time APIs into the following key categories for easy memorization
- Date, Time, DateTime – Classes/Methods (No Zone)
- DateTime with Zone – Classes/Methods
- Formatting/Parsing
- Common Operations – plus/minus
- Periods (Date-based differences)
- Duration (Time-based differences)
- Convert Legacy Date to New API
- Convert New API to Legacy Date
1. Date, Time, DateTime – Classes/Methods (No Zone)
| Class | Method/Example | Output (DD-MM-YYYY) | Use Case |
|---|---|---|---|
| LocalDate | LocalDate.now() | 31-01-2026 | Current date only (birthday, holiday) |
LocalDate.of(2026, 1, 31) | 31-01-2026 | Specific date | |
| LocalTime | LocalTime.now() | 14:30:25 | Current time only (meeting time) |
LocalTime.of(14, 30) | 14:30 | Specific time | |
| LocalDateTime | LocalDateTime.now() | 31-01-2026T14:30:25 | Current date + time (no zone) |
LocalDateTime.of(2026, 1, 31, 14, 30) | 31-01-2026T14:30 | Specific date-time |
2. Date/Time with Zone – Classes/Methods
| Class | Method/Example | Output (DD-MM-YYYY) | Use Case |
|---|---|---|---|
| ZoneId | ZoneId.of("Asia/Kolkata") | Asia/Kolkata | Define timezone |
| ZonedDateTime | ZonedDateTime.now() | 31-01-2026T14:30:25+05:30[Asia/Kolkata] | Current date-time with zone |
ZonedDateTime.now(ZoneId.of("America/New_York")) | 31-01-2026T04:00:25-05:00[America/New_York] | Specific zone time | |
ZonedDateTime.of(localDateTime, ZoneId.of("Asia/Kolkata")) | 31-01-2026T14:30+05:30[Asia/Kolkata] | Attach zone to LocalDateTime | |
| Instant | Instant.now() | 2026-01-31T09:00:25Z | UTC machine timestamp |
3. Formatting/Parsing
| Class/Method | Example Code | Output / Result | Use Case |
|---|---|---|---|
| DateTimeFormatter | DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm") | (formatter object) | Custom pattern |
| format | localDateTime.format(formatter) | 31-01-2026 14:30 | Date → String |
| parse | LocalDateTime.parse("31-01-2026 14:30", formatter) | LocalDateTime object | String → DateTime |
| Pre-defined | DateTimeFormatter.ISO_LOCAL_DATE.format(localDate) | 2026-01-31 | Standard ISO format |
4. Common Operations – plus/minus
| Operation | Example Code | Output (DD-MM-YYYY) | Use Case |
|---|---|---|---|
| plus | date.plusDays(10) | 10-02-2026 | Add days |
dateTime.plusMonths(2) | 31-03-2026T14:30 | Add months | |
| minus | date.minusYears(1) | 31-01-2025 | Subtract years |
| with (replace) | date.withDayOfMonth(15) | 15-01-2026 | Change day |
5. Periods (Date-based)
| Class/Method | Example Code | Output | Use Case |
|---|---|---|---|
| Period | Period.between(LocalDate.of(1990, 5, 15), LocalDate.of(2026, 1, 31)) | P35Y8M16D | Calculate age |
Period.ofMonths(3) | P3M | Fixed period | |
date.plus(period) | 30-04-2026 | Add period |
6. Duration (Time-based)
| Class/Method | Example Code | Output | Use Case |
|---|---|---|---|
| Duration | Duration.between(LocalTime.of(10, 0), LocalTime.of(15, 30)) | PT5H30M | Time difference |
Duration.ofHours(8) | PT8H | Fixed duration | |
time.plus(duration) | 22:30 | Add duration |
7. Convert Legacy Date to New API
| Method | Example Code | Result | Use Case |
|---|---|---|---|
| Date → New | Date legacy = new Date();
Instant instant = legacy.toInstant();
LocalDateTime ldt = LocalDateTime.ofInstant(instant, ZoneId.systemDefault()); | LocalDateTime (e.g., 31-01-2026T14:30) | Migrate old code to new API |
8. Convert New API to Legacy Date
| Method | Example Code | Result | Use Case |
|---|---|---|---|
| New → Date | LocalDateTime ldt = LocalDateTime.of(2026, 1, 31, 14, 30);
Instant instant = ldt.atZone(ZoneId.systemDefault()).toInstant();
Date legacy = Date.from(instant); | java.util.Date object | Use with legacy libraries |
Memory Tip
=> Local = no zone
=> Zoned = with zone
=> Instant = UTC machine time
=> Period = date diff (years/months/days)
=> Duration = time diff (hours/minutes/seconds)
What is Java 8 Date/Time API? Why better than old Date/Calendar?
=> Java 8 Date/Time API a immutable and thread safe API for handling dates, time, duration and periods to address the long standing flaws in the legacy classes java.util.date, java.util.calendar.
=> java.time is designed for production — immutable and thread-safe by default.
Java 8 Date/Time API |
Old Date, Calander classes |
Package : java.time |
Package : java.util.Date, Java.util.Calander |
All classes are immutable. ie. Operations return new instances |
Date and Calnder are mutable. ie. modifying one instance can affect others unexpectedly |
Thread safe and so ideal for concurrent applications |
Concurrent modifications lead to bugs |
=>
Separate classes for date, time, date-time, with consistent
methods
(DST
– Daylight Saving Time) |
=>
No separate methods for date, time, timezone concepts. |
Use case : Always prefer java.time over legacy classes |
Cannot prefer over Java 8 Date/Time API |
Example
:
|
Example
: |
Key classes: LocalDate, LocalTime, LocalDateTime, ZonedDateTime, Instant.
=> The java.time package has specialized classes for different needs
=> LocalDate: Date without time or timezone (year-month-day).
Example: Birthday, holiday.
LocalDate date = LocalDate.of(2025, 12, 26);
=> LocalTime: Time without date or timezone (hour-minute-second-nano).
Example: Meeting time in local context.
LocalTime time = LocalTime.of(14, 30);
=> LocalDateTime: Combination of LocalDate + LocalTime (no timezone).
Example: Event timestamp without zone.
LocalDateTime dt = LocalDateTime.now();
=> ZonedDateTime: LocalDateTime + timezone (handles DST, offsets).
Example: Global meeting time.
ZonedDateTime zdt = ZonedDateTime.now(ZoneId.of("Asia/Kolkata"));
=> Instant: Machine timestamp (UTC, seconds + nanos since epoch).
Example: Logging, timestamps in databases.
Instant instant = Instant.now();
=> Best Practice: Use the most specific class needed — LocalDateTime for most cases, ZonedDateTime for zone-aware, Instant for storage.
Common operations: plus/minus, Period, Duration, formatting/parsing.
=> plus/minus: Chainable methods to add/subtract units.
LocalDate date = LocalDate.now();
LocalDate future = date.plusDays(10).plusMonths(2).minusYears(1);
=> Period: Date-based amount (years, months, days).
Period period = Period.between(LocalDate.of(2025, 1, 1), LocalDate.of(2026, 1, 1)); // P1Y
LocalDate newDate = date.plus(period);
=> Duration: Time-based amount (hours, minutes, seconds, nanos).
Duration duration = Duration.ofHours(5);
LocalTime newTime = time.plus(duration);
=> Formatting/Parsing:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm");
String text = zdt.format(formatter);
ZonedDateTime parsed = ZonedDateTime.parse(text, formatter);
=> Best Practice: Use DateTimeFormatter for custom formats; pre-defined ISO_LOCAL_DATE for standard.
Time zones and ZoneId — examples.
=> ZoneId: Represents timezone (e.g., "Asia/Kolkata", "America/New_York").
ZoneId kolkata = ZoneId.of("Asia/Kolkata");
ZoneId ny = ZoneId.of("America/New_York");
=> With ZonedDateTime:
ZonedDateTime kolkataTime = ZonedDateTime.now(kolkata);
ZonedDateTime nyTime = kolkataTime.withZoneSameInstant(ny); // Convert to NY time
=> ZoneOffset: Fixed offset (e.g., +05:30 for IST)
ZoneOffset ist = ZoneOffset.of("+05:30");
=> Best Practice: Store in UTC (Instant), display in user's ZoneId.
Difference between Period and Duration.
Aspect |
Period |
Duration |
|---|---|---|
Unit |
Date-based |
Time-based |
Use Case |
Human dates (birthdays, anniversaries) |
Machine time (timers, intervals) |
Example |
Period.ofYears(1) = P1Y |
Duration.ofHours(24) = PT24H |
Add to |
LocalDate, LocalDateTime |
LocalTime, LocalDateTime, Instant |
Precision |
Calendar differences (handles months/years) |
Exact nanos |
Code Example :
Period p = Period.ofDays(30); // 30 days
Duration d = Duration.ofDays(30); // Exactly 30*24 hours
=> Best Practice: Use Period for date differences, Duration for time.
How to handle legacy Date with new API (toInstant, from).
Convert between legacy and new API
=> Legacy Date/Calendar to new:
Date oldDate = new Date();
Instant instant = oldDate.toInstant();
ZonedDateTime zdt = instant.atZone(ZoneId.systemDefault());
LocalDateTime ldt = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
=> New to legacy:
LocalDateTime ldt = LocalDateTime.now();
Instant instant = ldt.atZone(ZoneId.systemDefault()).toInstant();
Date legacyDate = Date.from(instant);
=> Best Practice: Convert at boundaries (e.g., DB/API) — use new API internally.
Best practices for Date/Time in production (immutability, thread-safety).=> Immutability: All java.time classes are immutable — never modify, always create new instances.
=> Thread-Safety: Safe for concurrent use (no synchronization needed).
=> Store in UTC: Use Instant or OFFSET for storage.
=> Display in User Zone: Convert with ZoneId for UI.
=> Avoid Legacy: Don't mix Date/Calendar unless forced.
=> Use DateTimeFormatter Carefully: Pre-defined ISO formats or thread-safe custom (not shared mutable formatter).
=> Handle Nulls: Use Optional or default values.
=> Code Example (Thread-Safe):
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
String text = localDate.format(formatter); // Safe in multi-thread
_______________________________________________________________
Practice the following coding exercises
- Reduce to sum of integers in list.
- Reduce to product of integers.
- Reduce to concatenate strings with delimiter.
- FlatMap: Flatten List<List<String>> to List<String>.
- FlatMap: Flatten List<Optional<String>> to List<String>.
- Generate 10 random numbers using Stream.generate + limit.
- Generate even numbers sequence using Stream.iterate + limit.
- Create LocalDate for today and print.
- Add 10 days to today's date using plusDays.
- Calculate age from birth date using Period.between.
- Parse string to LocalDateTime using DateTimeFormatter.
- Format LocalDateTime to custom pattern (e.g., "dd-MM-yyyy HH:mm").
- Get current time in different time zones (ZoneId.of("Asia/Kolkata"), "America/New_York").
- Convert old Date to LocalDateTime.
- Duration between two LocalDateTime.
- Find max/min date in list of LocalDate.
- Group dates by month using groupingBy.
- Infinite stream of Fibonacci numbers (limit 10).
- Stream of primes (generate + filter + limit).
- Debug Stream with peek (print intermediate values).