⚡IntermediateModern Java

Date and Time API

Work with dates, times, and durations using the modern java.time API (Java 8+): LocalDate, LocalTime, LocalDateTime, and Duration.

Overview

The old java.util.Date and Calendar classes are notoriously hard to use, mutable, and not thread-safe. Java 8 introduced the java.time package with a clean, immutable API. Key classes: - LocalDate: a date without time (2024-03-15) - LocalTime: a time without date (14:30:00) - LocalDateTime: date and time without timezone - ZonedDateTime: date, time, and timezone - Duration: amount of time between two instants - Period: amount of time between two dates (years, months, days) - DateTimeFormatter: parse and format dates

Key Points

  • •LocalDate.now(), LocalDate.of(year, month, day)
  • •LocalTime.now(), LocalTime.of(hour, minute)
  • •LocalDateTime.now(), LocalDateTime.of(date, time)
  • •All java.time objects are immutable: plus/minus methods return new objects
  • •Duration.between(start, end) for time-based duration
  • •Period.between(date1, date2) for date-based duration
  • •DateTimeFormatter.ofPattern("dd/MM/yyyy") for custom formatting
  • •date.format(formatter) and LocalDate.parse(str, formatter)
  • •ChronoUnit.DAYS.between(date1, date2) for counting units

Examples

LocalDate operations

import java.time.*;
import java.time.temporal.ChronoUnit;

public class Main {
    public static void main(String[] args) {
        LocalDate today = LocalDate.now();
        LocalDate birthday = LocalDate.of(1990, 6, 15);

        System.out.println("Today: " + today);
        System.out.println("Birthday: " + birthday);

        // Arithmetic: returns new object (immutable)
        LocalDate nextMonth = today.plusMonths(1);
        LocalDate lastYear = today.minusYears(1);
        System.out.println("Next month: " + nextMonth);
        System.out.println("Last year: " + lastYear);

        // Parts
        System.out.println("Year: " + today.getYear());
        System.out.println("Month: " + today.getMonth()); // JUNE
        System.out.println("Day of week: " + today.getDayOfWeek()); // FRIDAY

        // Comparison
        System.out.println("Is birthday in past: " + birthday.isBefore(today));

        // Difference
        long days = ChronoUnit.DAYS.between(birthday, today);
        System.out.println("Days since birthday: " + days);

        Period age = Period.between(birthday, today);
        System.out.println("Age: " + age.getYears() + " years, " + age.getMonths() + " months");
    }
}

All java.time objects are immutable. today.plusMonths(1) does not change today; it returns a new LocalDate.

LocalDateTime and Duration

import java.time.*;

public class Main {
    public static void main(String[] args) throws InterruptedException {
        LocalDateTime start = LocalDateTime.now();
        System.out.println("Start: " + start);

        // Simulate some work
        Thread.sleep(50);

        LocalDateTime end = LocalDateTime.now();
        Duration elapsed = Duration.between(start, end);
        System.out.println("Elapsed: " + elapsed.toMillis() + "ms");

        // Duration creation
        Duration twoHours = Duration.ofHours(2);
        Duration thirtyMin = Duration.ofMinutes(30);
        Duration total = twoHours.plus(thirtyMin);
        System.out.println("Total: " + total.toHours() + "h " + total.toMinutesPart() + "m");

        // LocalDateTime arithmetic
        LocalDateTime meeting = LocalDateTime.of(2024, 6, 15, 14, 30);
        LocalDateTime reminder = meeting.minusHours(1).minusMinutes(15);
        System.out.println("Meeting: " + meeting);
        System.out.println("Reminder at: " + reminder);
    }
}

Duration.toHours() returns total hours; toHoursPart() returns the hours portion (0-23). Use the Part methods when you need individual units from a duration.

Formatting and parsing dates

import java.time.*;
import java.time.format.*;

public class Main {
    public static void main(String[] args) {
        // Predefined formatters
        LocalDate date = LocalDate.of(2024, 3, 15);
        System.out.println(date.format(DateTimeFormatter.ISO_DATE)); // 2024-03-15
        System.out.println(date.format(DateTimeFormatter.ofPattern("dd/MM/yyyy"))); // 15/03/2024
        System.out.println(date.format(DateTimeFormatter.ofPattern("MMMM d, yyyy"))); // March 15, 2024

        // Parsing
        DateTimeFormatter fmt = DateTimeFormatter.ofPattern("dd-MM-yyyy");
        LocalDate parsed = LocalDate.parse("25-12-2024", fmt);
        System.out.println("Parsed: " + parsed);

        // Time formatting
        LocalTime time = LocalTime.of(14, 30, 45);
        System.out.println(time.format(DateTimeFormatter.ofPattern("hh:mm a"))); // 02:30 PM
        System.out.println(time.format(DateTimeFormatter.ofPattern("HH:mm:ss"))); // 14:30:45

        // LocalDateTime
        LocalDateTime dt = LocalDateTime.of(date, time);
        System.out.println(dt.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")));
    }
}

DateTimeFormatter.ofPattern() uses the same letter codes as SimpleDateFormat, but it is immutable and thread-safe unlike SimpleDateFormat.

Common Mistakes

  • Mutating java.time objects. Methods like plusDays() return a new object; they do not modify the original. Always assign the result: date = date.plusDays(1)
  • Using java.util.Date or Calendar in new code. These are the old API and should be avoided. Use java.time classes instead
  • Forgetting to handle timezone when comparing times across regions. LocalDateTime has no timezone; use ZonedDateTime when timezone matters

Note

For user-facing date formatting, use DateTimeFormatter.ofLocalizedDate(FormatStyle.LONG) which formats dates according to the user's locale. For machine-readable formats, use DateTimeFormatter.ISO_DATE or a fixed pattern.

Exercises

Write Java code and click Run to execute it instantly. When your output looks correct, mark as done.

Loading editor…

Completed: 0 / 4 exercises

Knowledge Check

Question 1 of 4

What does LocalDate.plusDays(5) return?