When tracking birthdays, deadlines, or scheduling events, you need to work with calendar dates. LocalDate provides a clean API for date manipulation without the complexity of time zones, replacing the error-prone legacy Date class.

LocalDate represents a date without time in the ISO calendar system (year-month-day). It's part of the java.time package introduced in Java 8.

Getting Current Date

Current.java
// Current date

import java.time.LocalDate;

public class Current {

    public static void main(String[] args) {
        // Static replay uses a fixed sample "today".
        LocalDate today = LocalDate.of(2025, 1, 29);
        System.out.println("Sample today: " + today);

        // Date components
        int year = today.getYear();
        int month = today.getMonthValue();
        int day = today.getDayOfMonth();

        System.out.println("\nDate components:");
        System.out.println("Year: " + year);
        System.out.println("Month: " + month);
        System.out.println("Day: " + day);

        // Day of week
        System.out.println("Day of week: " + today.getDayOfWeek());

        // Day of year
        System.out.println("Day of year: " + today.getDayOfYear());

        // Month name
        System.out.println("Month name: " + today.getMonth());

        // Is leap year
        System.out.println("Leap year: " + today.isLeapYear());

        // Length of month
        System.out.println("Days in month: " + today.lengthOfMonth());

        // Length of year
        System.out.println("Days in year: " + today.lengthOfYear());
    }

}
LocalDate An immutable date object representing year, month, and day without time or timezone information.

Creating Specific Dates

Create.java
// Create specific date

import java.time.LocalDate;
import java.time.Month;

public class Create {

    public static void main(String[] args) {
        // Create with year, month, day
        LocalDate date1 = ;
        System.out.println("Date 1: " + date1);

        // Create with Month enum
        LocalDate date2 = LocalDate.of(2025, Month.JANUARY, 29);
        System.out.println("Date 2: " + date2);

        // Special dates
        LocalDate newYear = LocalDate.of(2025, 1, 1);
        System.out.println("\nNew Year 2025: " + newYear);

        LocalDate christmas = LocalDate.of(2025, 12, 25);
        System.out.println("Christmas 2025: " + christmas);

        // First day of month
        LocalDate today = LocalDate.of(2025, 1, 29);
        LocalDate firstOfMonth = today.withDayOfMonth(1);
        System.out.println("\nFirst of this month: " + firstOfMonth);

        // Last day of month
        LocalDate lastOfMonth = today.withDayOfMonth(today.lengthOfMonth());
        System.out.println("Last of this month: " + lastOfMonth);

        // First day of year
        LocalDate firstOfYear = today.withDayOfYear(1);
        System.out.println("First of this year: " + firstOfYear);

        // Change components
        LocalDate modified = date1.withYear(2026).withMonth(6).withDayOfMonth(15);
        System.out.println("\nModified date: " + modified);

        // Min and max dates
        LocalDate min = LocalDate.MIN;
        LocalDate max = LocalDate.MAX;
        System.out.println("\nMin date: " + min);
        System.out.println("Max date: " + max);

        // Epoch (1970-01-01)
        LocalDate epoch = LocalDate.ofEpochDay(0);
        System.out.println("Epoch: " + epoch);
    }

}
// Create specific date

import java.time.LocalDate;
import java.time.Month;

public class Create {

    public static void main(String[] args) {
        // Create with year, month, day
        LocalDate date1 = ;
        System.out.println("Date 1: " + date1);

        // Create with Month enum
        LocalDate date2 = LocalDate.of(2025, Month.JANUARY, 29);
        System.out.println("Date 2: " + date2);

        // Special dates
        LocalDate newYear = LocalDate.of(2025, 1, 1);
        System.out.println("\nNew Year 2025: " + newYear);

        LocalDate christmas = LocalDate.of(2025, 12, 25);
        System.out.println("Christmas 2025: " + christmas);

        // First day of month
        LocalDate today = LocalDate.of(2025, 1, 29);
        LocalDate firstOfMonth = today.withDayOfMonth(1);
        System.out.println("\nFirst of this month: " + firstOfMonth);

        // Last day of month
        LocalDate lastOfMonth = today.withDayOfMonth(today.lengthOfMonth());
        System.out.println("Last of this month: " + lastOfMonth);

        // First day of year
        LocalDate firstOfYear = today.withDayOfYear(1);
        System.out.println("First of this year: " + firstOfYear);

        // Change components
        LocalDate modified = date1.withYear(2026).withMonth(6).withDayOfMonth(15);
        System.out.println("\nModified date: " + modified);

        // Min and max dates
        LocalDate min = LocalDate.MIN;
        LocalDate max = LocalDate.MAX;
        System.out.println("\nMin date: " + min);
        System.out.println("Max date: " + max);

        // Epoch (1970-01-01)
        LocalDate epoch = LocalDate.ofEpochDay(0);
        System.out.println("Epoch: " + epoch);
    }

}

Date Components

Components.java
// Date components

import java.time.LocalDate;
import java.time.DayOfWeek;
import java.time.Month;

public class Components {

    public static void main(String[] args) {
        LocalDate date = ;
        
        System.out.println("Date: " + date);
        System.out.println();

        // Year, month, day
        System.out.println("Year: " + date.getYear());
        System.out.println("Month (int): " + date.getMonthValue());
        System.out.println("Day: " + date.getDayOfMonth());

        // Month enum
        Month month = date.getMonth();
        System.out.println("\nMonth enum: " + month);
        System.out.println("Month name: " + month.name());
        System.out.println("Month value: " + month.getValue());

        // Day of week
        DayOfWeek dayOfWeek = date.getDayOfWeek();
        System.out.println("\nDay of week enum: " + dayOfWeek);
        System.out.println("Day name: " + dayOfWeek.name());
        System.out.println("Day value: " + dayOfWeek.getValue());  // 1=Monday, 7=Sunday

        // Day of year
        System.out.println("\nDay of year: " + date.getDayOfYear());

        // Era
        System.out.println("Era: " + date.getEra());  // CE or BCE

        // Check properties
        System.out.println("\nIs leap year: " + date.isLeapYear());
        System.out.println("Length of month: " + date.lengthOfMonth());
        System.out.println("Length of year: " + date.lengthOfYear());

        // Convert to epoch day
        long epochDay = date.toEpochDay();
        System.out.println("\nDays since epoch (1970-01-01): " + epochDay);

        // Multiple dates
        System.out.println("\nWeek dates:");
        LocalDate monday = LocalDate.of(2025, 1, 27);
        for (int i = 0; i < 7; i++) {
            LocalDate day = monday.plusDays(i);
            System.out.println(day + " is " + day.getDayOfWeek());
        }
    }

}
// Date components

import java.time.LocalDate;
import java.time.DayOfWeek;
import java.time.Month;

public class Components {

    public static void main(String[] args) {
        LocalDate date = ;
        
        System.out.println("Date: " + date);
        System.out.println();

        // Year, month, day
        System.out.println("Year: " + date.getYear());
        System.out.println("Month (int): " + date.getMonthValue());
        System.out.println("Day: " + date.getDayOfMonth());

        // Month enum
        Month month = date.getMonth();
        System.out.println("\nMonth enum: " + month);
        System.out.println("Month name: " + month.name());
        System.out.println("Month value: " + month.getValue());

        // Day of week
        DayOfWeek dayOfWeek = date.getDayOfWeek();
        System.out.println("\nDay of week enum: " + dayOfWeek);
        System.out.println("Day name: " + dayOfWeek.name());
        System.out.println("Day value: " + dayOfWeek.getValue());  // 1=Monday, 7=Sunday

        // Day of year
        System.out.println("\nDay of year: " + date.getDayOfYear());

        // Era
        System.out.println("Era: " + date.getEra());  // CE or BCE

        // Check properties
        System.out.println("\nIs leap year: " + date.isLeapYear());
        System.out.println("Length of month: " + date.lengthOfMonth());
        System.out.println("Length of year: " + date.lengthOfYear());

        // Convert to epoch day
        long epochDay = date.toEpochDay();
        System.out.println("\nDays since epoch (1970-01-01): " + epochDay);

        // Multiple dates
        System.out.println("\nWeek dates:");
        LocalDate monday = LocalDate.of(2025, 1, 27);
        for (int i = 0; i < 7; i++) {
            LocalDate day = monday.plusDays(i);
            System.out.println(day + " is " + day.getDayOfWeek());
        }
    }

}
date_components Individual parts of a date that can be extracted: year, month (1-12), day of month, day of week, day of year.

Comparing Dates

Compare.java
// Compare dates

import java.time.LocalDate;

public class Compare {

    public static void main(String[] args) {
        LocalDate date1 = LocalDate.of(2025, 1, 29);
        LocalDate date2 = LocalDate.of(2025, 2, 15);
        LocalDate date3 = LocalDate.of(2025, 1, 29);

        System.out.println("Date 1: " + date1);
        System.out.println("Date 2: " + date2);
        System.out.println("Date 3: " + date3);
        System.out.println();

        // isBefore, isAfter
        System.out.println("date1.isBefore(date2): " + date1.isBefore(date2));
        System.out.println("date1.isAfter(date2): " + date1.isAfter(date2));

        // equals
        System.out.println("\ndate1.equals(date2): " + date1.equals(date2));
        System.out.println("date1.equals(date3): " + date1.equals(date3));

        // compareTo
        System.out.println("\ndate1.compareTo(date2): " + date1.compareTo(date2));  // negative
        System.out.println("date2.compareTo(date1): " + date2.compareTo(date1));  // positive
        System.out.println("date1.compareTo(date3): " + date1.compareTo(date3));  // zero

        // isEqual (handles null better)
        System.out.println("\ndate1.isEqual(date3): " + date1.isEqual(date3));

        // Today comparisons
        LocalDate today = LocalDate.of(2025, 1, 29);
        System.out.println("\nSample today: " + today);
        System.out.println("date1 is before today: " + date1.isBefore(today));
        System.out.println("date1 is after today: " + date1.isAfter(today));

        // Find earliest/latest
        LocalDate earliest = date1.isBefore(date2) ? date1 : date2;
        LocalDate latest = date1.isAfter(date2) ? date1 : date2;
        
        System.out.println("\nEarliest: " + earliest);
        System.out.println("Latest: " + latest);

        // Check if in range
        LocalDate check = ;
        LocalDate start = LocalDate.of(2025, 1, 1);
        LocalDate end = LocalDate.of(2025, 2, 1);

        boolean inRange = !check.isBefore(start) && !check.isAfter(end);
        System.out.println("\n" + check + " is in range [" + start + ", " + end + "]: " + inRange);

        // Sort dates
        LocalDate[] dates = {
            LocalDate.of(2025, 3, 15),
            LocalDate.of(2025, 1, 10),
            LocalDate.of(2025, 2, 20)
        };

        System.out.println("\nBefore sort:");
        for (LocalDate d : dates) {
            System.out.println("  " + d);
        }

        java.util.Arrays.sort(dates);

        System.out.println("After sort:");
        for (LocalDate d : dates) {
            System.out.println("  " + d);
        }
    }

}
// Compare dates

import java.time.LocalDate;

public class Compare {

    public static void main(String[] args) {
        LocalDate date1 = LocalDate.of(2025, 1, 29);
        LocalDate date2 = LocalDate.of(2025, 2, 15);
        LocalDate date3 = LocalDate.of(2025, 1, 29);

        System.out.println("Date 1: " + date1);
        System.out.println("Date 2: " + date2);
        System.out.println("Date 3: " + date3);
        System.out.println();

        // isBefore, isAfter
        System.out.println("date1.isBefore(date2): " + date1.isBefore(date2));
        System.out.println("date1.isAfter(date2): " + date1.isAfter(date2));

        // equals
        System.out.println("\ndate1.equals(date2): " + date1.equals(date2));
        System.out.println("date1.equals(date3): " + date1.equals(date3));

        // compareTo
        System.out.println("\ndate1.compareTo(date2): " + date1.compareTo(date2));  // negative
        System.out.println("date2.compareTo(date1): " + date2.compareTo(date1));  // positive
        System.out.println("date1.compareTo(date3): " + date1.compareTo(date3));  // zero

        // isEqual (handles null better)
        System.out.println("\ndate1.isEqual(date3): " + date1.isEqual(date3));

        // Today comparisons
        LocalDate today = LocalDate.of(2025, 1, 29);
        System.out.println("\nSample today: " + today);
        System.out.println("date1 is before today: " + date1.isBefore(today));
        System.out.println("date1 is after today: " + date1.isAfter(today));

        // Find earliest/latest
        LocalDate earliest = date1.isBefore(date2) ? date1 : date2;
        LocalDate latest = date1.isAfter(date2) ? date1 : date2;
        
        System.out.println("\nEarliest: " + earliest);
        System.out.println("Latest: " + latest);

        // Check if in range
        LocalDate check = ;
        LocalDate start = LocalDate.of(2025, 1, 1);
        LocalDate end = LocalDate.of(2025, 2, 1);

        boolean inRange = !check.isBefore(start) && !check.isAfter(end);
        System.out.println("\n" + check + " is in range [" + start + ", " + end + "]: " + inRange);

        // Sort dates
        LocalDate[] dates = {
            LocalDate.of(2025, 3, 15),
            LocalDate.of(2025, 1, 10),
            LocalDate.of(2025, 2, 20)
        };

        System.out.println("\nBefore sort:");
        for (LocalDate d : dates) {
            System.out.println("  " + d);
        }

        java.util.Arrays.sort(dates);

        System.out.println("After sort:");
        for (LocalDate d : dates) {
            System.out.println("  " + d);
        }
    }

}
immutability LocalDate cannot be modified after creation. Methods like plusDays() return a new LocalDate instance.

Parsing Dates

Parse.java
// Parse date string

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.Locale;

public class Parse {

    public static void main(String[] args) {
        // Parse ISO format (yyyy-MM-dd)
        String iso = ;
        LocalDate date1 = LocalDate.parse(iso);
        System.out.println("Parsed ISO: " + date1);

        // Parse with custom pattern
        String custom1 = "29/01/2025";
        DateTimeFormatter formatter1 = DateTimeFormatter.ofPattern("dd/MM/yyyy");
        LocalDate date2 = LocalDate.parse(custom1, formatter1);
        System.out.println("Parsed " + custom1 + ": " + date2);

        // Parse various formats
        String[] dateStrings = {
            "2025-12-25",
            "25/12/2025",
            "12-25-2025",
            "Dec 25, 2025"
        };

        DateTimeFormatter[] formatters = {
            DateTimeFormatter.ISO_LOCAL_DATE,
            DateTimeFormatter.ofPattern("dd/MM/yyyy"),
            DateTimeFormatter.ofPattern("MM-dd-yyyy"),
            DateTimeFormatter.ofPattern("MMM dd, yyyy", Locale.US)
        };

        System.out.println("\nParse various formats:");
        for (int i = 0; i < dateStrings.length; i++) {
            LocalDate date = LocalDate.parse(dateStrings[i], formatters[i]);
            System.out.println(dateStrings[i] + " -> " + date);
        }

        // Handle parse errors
        System.out.println("\nHandle parse errors:");
        String[] testDates = {
            "2025-01-29",
            "2025-13-01",   // invalid month
            "2025-02-30",   // invalid day
            "not-a-date"
        };

        for (String dateStr : testDates) {
            try {
                LocalDate date = LocalDate.parse(dateStr);
                System.out.println(dateStr + " -> " + date);
            } catch (DateTimeParseException e) {
                System.out.println(dateStr + " -> ERROR: " + e.getMessage());
            }
        }

        // Parse with validation
        System.out.println("\nSafe parse:");
        System.out.println(safeParseDate("2025-01-29"));
        System.out.println(safeParseDate("invalid"));

        // Parse from different separators
        String date3 = "2025/01/29";
        LocalDate parsed3 = LocalDate.parse(date3, DateTimeFormatter.ofPattern("yyyy/MM/dd"));
        System.out.println("\nParsed " + date3 + ": " + parsed3);

        // Parse with text month
        String date4 = "January 29, 2025";
        LocalDate parsed4 = LocalDate.parse(date4, DateTimeFormatter.ofPattern("MMMM dd, yyyy", Locale.US));
        System.out.println("Parsed " + date4 + ": " + parsed4);
    }

    public static LocalDate safeParseDate(String dateStr) {
        try {
            return LocalDate.parse(dateStr);
        } catch (DateTimeParseException e) {
            System.out.println("Invalid date: " + dateStr);
            return null;
        }
    }

}
// Parse date string

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.Locale;

public class Parse {

    public static void main(String[] args) {
        // Parse ISO format (yyyy-MM-dd)
        String iso = ;
        LocalDate date1 = LocalDate.parse(iso);
        System.out.println("Parsed ISO: " + date1);

        // Parse with custom pattern
        String custom1 = "29/01/2025";
        DateTimeFormatter formatter1 = DateTimeFormatter.ofPattern("dd/MM/yyyy");
        LocalDate date2 = LocalDate.parse(custom1, formatter1);
        System.out.println("Parsed " + custom1 + ": " + date2);

        // Parse various formats
        String[] dateStrings = {
            "2025-12-25",
            "25/12/2025",
            "12-25-2025",
            "Dec 25, 2025"
        };

        DateTimeFormatter[] formatters = {
            DateTimeFormatter.ISO_LOCAL_DATE,
            DateTimeFormatter.ofPattern("dd/MM/yyyy"),
            DateTimeFormatter.ofPattern("MM-dd-yyyy"),
            DateTimeFormatter.ofPattern("MMM dd, yyyy", Locale.US)
        };

        System.out.println("\nParse various formats:");
        for (int i = 0; i < dateStrings.length; i++) {
            LocalDate date = LocalDate.parse(dateStrings[i], formatters[i]);
            System.out.println(dateStrings[i] + " -> " + date);
        }

        // Handle parse errors
        System.out.println("\nHandle parse errors:");
        String[] testDates = {
            "2025-01-29",
            "2025-13-01",   // invalid month
            "2025-02-30",   // invalid day
            "not-a-date"
        };

        for (String dateStr : testDates) {
            try {
                LocalDate date = LocalDate.parse(dateStr);
                System.out.println(dateStr + " -> " + date);
            } catch (DateTimeParseException e) {
                System.out.println(dateStr + " -> ERROR: " + e.getMessage());
            }
        }

        // Parse with validation
        System.out.println("\nSafe parse:");
        System.out.println(safeParseDate("2025-01-29"));
        System.out.println(safeParseDate("invalid"));

        // Parse from different separators
        String date3 = "2025/01/29";
        LocalDate parsed3 = LocalDate.parse(date3, DateTimeFormatter.ofPattern("yyyy/MM/dd"));
        System.out.println("\nParsed " + date3 + ": " + parsed3);

        // Parse with text month
        String date4 = "January 29, 2025";
        LocalDate parsed4 = LocalDate.parse(date4, DateTimeFormatter.ofPattern("MMMM dd, yyyy", Locale.US));
        System.out.println("Parsed " + date4 + ": " + parsed4);
    }

    public static LocalDate safeParseDate(String dateStr) {
        try {
            return LocalDate.parse(dateStr);
        } catch (DateTimeParseException e) {
            System.out.println("Invalid date: " + dateStr);
            return null;
        }
    }

}

Key Methods

  • now(): Current date
  • of(year, month, day): Create specific date
  • getYear(), getMonthValue(), getDayOfMonth(): Get components
  • plusDays(), minusDays(): Add/subtract days
  • isBefore(), isAfter(): Compare dates
  • parse(): From string

Common Operations

  • Add/subtract days, weeks, months, years
  • Compare dates
  • Get day of week
  • Calculate difference
  • Format to string

Exercise: Practical.java

Calculate how many days until the next birthday given a birth date