Java LocalDate vysvětleno: Kompletní průvodce prací s daty v Java 8 a novějších

目次

Co je LocalDate?

Zpracování dat v Javě se od verze 8 významně vyvinulo. V centru tohoto vývoje stojí LocalDate. LocalDate je neměnný objekt, který představuje pouze datum (rok, měsíc a den, např. 2025-06-26), bez jakéhokoli konceptu času nebo časové zóny. Umožňuje vám zpracovávat dnešní datum nebo specifická kalendářní data jednoduchým a bezpečným způsobem.

Rozdíly od starých tříd pro data

Před Javou 8 se běžně používaly třídy jako java.util.Date a java.util.Calendar. Tyto třídy však měly několik problémů, včetně chybného designu (jako měsíce s nulovým indexem), nedostatku thread safety a neintuitivních API. V důsledku toho často vedly k chybám nebo neočekávanému chování.

LocalDate tyto problémy řeší a nabízí následující funkce:

  • Explicitní správa pouze roku, měsíce a dne (např. 26. června 2025)
  • Neměnný objekt (hodnoty nelze změnit, což zajišťuje bezpečnost)
  • Intuitivní názvy metod a design API (např. plusDays(1) pro následující den, getMonthValue() pro číslo měsíce)
  • Nezávislý na časové zóně (konzistentní chování bez ohledu na nastavení systému nebo serveru)

Kdy byste měli používat LocalDate?

LocalDate je ideální, když chcete zpracovávat data jasně, nepotřebujete informace o čase a chcete implementovat operace s daty bezpečně a snadno. Typické případy použití zahrnují:

  • Zaznamenávání dat bez času, jako narozeniny nebo výročí
  • Správa plánů, lhůt a termínů
  • Výpočet lhůt nebo zbývajících dní

Ze těchto důvodů lze LocalDate považovat za nový standard pro zpracování dat v Javě. V následující sekci vysvětlíme základní použití a inicializaci LocalDate podrobně.

Základní operace s LocalDate

LocalDate poskytuje intuitivní a jednoduché API pro manipulaci s daty. Tato sekce vysvětluje běžně používané funkce s konkrétními příklady.

Získání aktuálního data

Pro získání dnešního data použijte metodu LocalDate.now(). Vrátí aktuální systémové datum (nezávislé na časové zóně) jako instanci LocalDate.

import java.time.LocalDate;

LocalDate today = LocalDate.now();
System.out.println(today); // Example: 2025-06-26

Vytvoření specifického data

Pro vytvoření libovolného data v minulosti nebo budoucnosti použijte LocalDate.of(int year, int month, int dayOfMonth). To vám umožní volně vytvářet data jako 31. prosince 2024.

LocalDate specialDay = LocalDate.of(2024, 12, 31);
System.out.println(specialDay); // 2024-12-31

Parsování data z řetězce

Pro generování LocalDate z řetězce jako „2023-03-15“ použijte metodu LocalDate.parse(String text). Pokud řetězec následuje standardní ISO formát („YYYY-MM-DD“), není vyžadována žádná další konfigurace.

LocalDate parsedDate = LocalDate.parse("2023-03-15");
System.out.println(parsedDate); // 2023-03-15

Parsování s vlastním formátem (doplňek)

Pokud potřebujete zpracovávat data ve vlastním formátu jako „2023/03/15“, můžete kombinovat DateTimeFormatter s parse().

import java.time.format.DateTimeFormatter;

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd");
LocalDate formattedDate = LocalDate.parse("2023/03/15", formatter);
System.out.println(formattedDate); // 2023-03-15

Jak je uvedeno výše, základní operace LocalDate jsou intuitivní a přímočaré. V moderním kódu Javy je inicializace a konverze dat zřídka matoucí. V další kapitole vysvětlíme, jak extrahovat hodnoty roku, měsíce, dne a dne v týdnu z LocalDate.

Získávání roku, měsíce, dne a dne v týdnu

LocalDate vám umožňuje snadno extrahovat nejen samotné datum, ale i jednotlivé komponenty jako rok, měsíc, den a den v týdnu. Tato sekce vysvětluje, jak získat tyto běžně používané prvky.

Získání roku, měsíce a dne

Pro získání každé komponenty z instance LocalDate použijte dedikované getter metody.

LocalDate date = LocalDate.of(2025, 6, 26);

int year = date.getYear();           // Year (e.g. 2025)
int month = date.getMonthValue();    // Month as a number (1–12, e.g. 6)
int day = date.getDayOfMonth();      // Day of month (1–31, e.g. 26)

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

Získání názvů měsíců a dnů v týdnu

LocalDate také podporuje získávání názvů měsíců a dnů v týdnu, což je užitečné, když potřebujete textové reprezentace.

  • Název měsíce (anglická reprezentace) Použití getMonth() vrací hodnotu výčtu Month (např. JUNE).
    import java.time.Month;
    
    Month monthName = date.getMonth(); // JUNE (uppercase English)
    System.out.println(monthName);
    
  • Název dne v týdnu getDayOfWeek() vrací výčet DayOfWeek (např. THURSDAY).
    import java.time.DayOfWeek;
    
    DayOfWeek dayOfWeek = date.getDayOfWeek(); // THURSDAY (uppercase English)
    System.out.println(dayOfWeek);
    

Zobrazení názvů měsíců a dnů v týdnu v japonštině

Pokud chcete zobrazit názvy měsíců nebo dnů v týdnu v japonštině místo angličtiny, můžete výstup přizpůsobit pomocí DateTimeFormatter.

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

DateTimeFormatter formatter =
    DateTimeFormatter.ofPattern("yyyy年MM月dd日(E)", Locale.JAPANESE);
String formatted = date.format(formatter); // 2025年06月26日(木)
System.out.println(formatted);

Shrnutí získaných komponent

Jednou z hlavních předností LocalDate je, že umožňuje získat rok, měsíc, den a den v týdnu pomocí intuitivních metod. Tato flexibilita značně usnadňuje práci s daty v obchodních a webových aplikacích.

Výpočty dat (přičítání a odečítání)

Výpočty dat, jako je přidávání nebo odečítání dnů, jsou často potřebné pro správu rozvrhů a výpočty termínů. S LocalDate můžete bezpečně a intuitivně provádět operace jako „tři dny později“, „týden dříve“ nebo „rozdíl mezi dvěma daty“.

Přidávání dat

  • Přidávání dnů
    LocalDate today = LocalDate.of(2025, 6, 26);
    LocalDate threeDaysLater = today.plusDays(3); // Three days later
    System.out.println(threeDaysLater); // 2025-06-29
    
  • Přidávání měsíců nebo let
    LocalDate nextMonth = today.plusMonths(1); // One month later
    LocalDate nextYear = today.plusYears(1);   // One year later
    System.out.println(nextMonth); // 2025-07-26
    System.out.println(nextYear);  // 2026-06-26
    

Odečítání dat

  • Odečítání dnů, měsíců nebo let
    LocalDate lastWeek = today.minusWeeks(1);   // One week earlier
    LocalDate previousDay = today.minusDays(1); // Previous day
    System.out.println(lastWeek);    // 2025-06-19
    System.out.println(previousDay); // 2025-06-25
    

Výpočet rozdílů mezi daty

  • Výpočet rozdílu ve dnech
    import java.time.temporal.ChronoUnit;
    
    LocalDate start = LocalDate.of(2025, 6, 1);
    LocalDate end = LocalDate.of(2025, 6, 26);
    
    long daysBetween = ChronoUnit.DAYS.between(start, end); // 25
    System.out.println(daysBetween); // 25
    
  • Výpočet rozdílů pomocí jiných jednotek (měsíce, roky)
    long monthsBetween = ChronoUnit.MONTHS.between(start, end); // 0
    long yearsBetween = ChronoUnit.YEARS.between(start, end);   // 0
    

Shrnutí

Používáním metod pro přičítání a odečítání v LocalDate můžete snadno implementovat běžné výpočty dat, jako je „termín příštího měsíce“ nebo „dny od poslední události“.

Protože je LocalDate neměnný, původní instance není nikdy upravena. Každá operace vrací novou instanci LocalDate, což zajišťuje bezpečnou manipulaci s daty.

Pokročilé operace: úprava konkrétních dat

V reálném světě práce s daty často nestačí jednoduché přičítání nebo odečítání. Běžné požadavky zahrnují určení „posledního dne v měsíci“ nebo „prvního dne v následujícím měsíci“. LocalDate poskytuje pohodlné API pro tyto typy úprav.

Using TemporalAdjuster

S LocalDate můžete kombinovat metodu with() a TemporalAdjuster, abyste prováděli intuitivní operace, jako je „konec měsíce“, „začátek měsíce“ nebo „další konkrétní den v týdnu“. Vestavěné adjustéry jsou k dispozici ve třídě TemporalAdjusters.

Getting the First and Last Day of a Month

  • Getting the last day of the month
    import java.time.LocalDate;
    import java.time.temporal.TemporalAdjusters;
    
    LocalDate date = LocalDate.of(2025, 6, 26);
    LocalDate endOfMonth = date.with(TemporalAdjusters.lastDayOfMonth());
    System.out.println(endOfMonth); // 2025-06-30
    
  • Getting the first day of the month
    LocalDate startOfMonth = date.with(TemporalAdjusters.firstDayOfMonth());
    System.out.println(startOfMonth); // 2025-06-01
    

Adjusting Based on Weekdays

Úpravy na základě dnů v týdnu – například „druhé pondělí v měsíci“ nebo „příští pátek“ – jsou také snadno implementovatelné.

  • Getting the next Friday
    import java.time.DayOfWeek;
    
    LocalDate nextFriday =
        date.with(TemporalAdjusters.next(DayOfWeek.FRIDAY));
    System.out.println(nextFriday); // 2025-06-27
    
  • Getting the second Monday of the current month
    LocalDate secondMonday =
        date.with(TemporalAdjusters.dayOfWeekInMonth(2, DayOfWeek.MONDAY));
    System.out.println(secondMonday); // 2025-06-09
    

Adjusting to the Beginning or End of a Year

Stejný přístup můžete použít k získání prvního nebo posledního dne v roce.

LocalDate startOfYear =
    date.with(TemporalAdjusters.firstDayOfYear());
LocalDate endOfYear =
    date.with(TemporalAdjusters.lastDayOfYear());

System.out.println(startOfYear); // 2025-01-01
System.out.println(endOfYear);   // 2025-12-31

Creating Custom Adjusters

Pokud potřebujete vlastní logiku úpravy data založenou na konkrétních obchodních pravidlech, můžete si sami implementovat rozhraní TemporalAdjuster.

Kombinací LocalDate s TemporalAdjusters se i složité výpočty dat stávají intuitivními a flexibilními. To je zvláště užitečné při práci s termíny nebo specifickými obchodními plány.

Working with LocalDate and LocalDateTime

V rámci Java Date and Time API (balíček java.time) představuje LocalDate pouze datum, zatímco LocalDateTime představuje datum i čas. V praxi vývojáři často potřebují převádět mezi těmito dvěma typy. Tato sekce vysvětluje, jak provádět tyto konverze.

Converting LocalDate to LocalDateTime

Chcete-li k LocalDate přidat časové informace a převést jej na LocalDateTime, použijte atTime() nebo atStartOfDay().

  • Adding a specific time
    import java.time.LocalDate;
    import java.time.LocalDateTime;
    
    LocalDate date = LocalDate.of(2025, 6, 26);
    LocalDateTime dateTime =
        date.atTime(14, 30, 0); // 2025-06-26 14:30:00
    System.out.println(dateTime);
    
  • Creating a LocalDateTime at the start of the day
    LocalDateTime startOfDay =
        date.atStartOfDay(); // 2025-06-26T00:00
    System.out.println(startOfDay);
    

Converting LocalDateTime to LocalDate

Chcete-li získat pouze datumovou část z LocalDateTime, použijte metodu toLocalDate().

import java.time.LocalDateTime;

LocalDateTime dateTime =
    LocalDateTime.of(2025, 6, 26, 14, 30);
LocalDate dateOnly = dateTime.toLocalDate();
System.out.println(dateOnly); // 2025-06-26

Combining LocalDate with LocalTime

Můžete také kombinovat LocalDate a LocalTime a vytvořit tak LocalDateTime.

import java.time.LocalTime;

LocalTime time = LocalTime.of(9, 0);
LocalDateTime combined =
    date.atTime(time); // 2025-06-26T09:00
System.out.println(combined);

Summary

  • Převod LocalDate na LocalDateTime pomocí atTime() nebo atStartOfDay()
  • Převod LocalDateTime na LocalDate pomocí toLocalDate()
  • Oddělování a kombinování data a času je běžné v reálných systémech

Exception Handling and Best Practices

.Date handling can easily lead to unexpected exceptions if invalid values or formats are used. Even when working with LocalDate, exceptions may occur due to non-existent dates or parsing errors. This section explains common exceptions and best practices for handling them safely.

Specifikace neexistujícího data

If you attempt to create a date that does not exist—such as February 30, 2023— a DateTimeException will be thrown.

import java.time.LocalDate;

// Example that throws an exception
LocalDate invalidDate = LocalDate.of(2023, 2, 30);

In such cases, it is important to catch the exception and handle it appropriately.

try {
    LocalDate invalidDate = LocalDate.of(2023, 2, 30);
} catch (DateTimeException e) {
    System.out.println("An invalid date was specified: " + e.getMessage());
}

Výjimky při parsování řetězců

When using LocalDate.parse(), a DateTimeParseException is thrown if the string format is invalid or the date itself does not exist.

import java.time.format.DateTimeParseException;

try {
    LocalDate date = LocalDate.parse("2023/02/30");
} catch (DateTimeParseException e) {
    System.out.println("Failed to parse date: " + e.getMessage());
}

Osvědčené postupy

  • Validate input values in advance When accepting user input, validate both the format and value before parsing to prevent exceptions.
  • Catch exceptions and provide user-friendly messages Instead of allowing the application to crash, return clear and understandable error messages to the user.
  • Leverage immutability Because LocalDate is immutable, always treat calculation results as new instances rather than overwriting existing ones.

Časté úskalí

  • Handling February 29 in leap years
  • Specifying values outside valid ranges (e.g. month = 13, day = 0)
  • Mismatched formats during string parsing

These issues are especially common among beginners, so extra care is required.

Praktické příklady použití LocalDate

LocalDate is not limited to simple date storage—it is widely used in real-world business systems and applications. Below are several practical examples.

Birthday and Age Calculation

Calculating a person’s age based on their birth date is a classic use case. Using LocalDate together with Period makes this easy.

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

LocalDate birthDay = LocalDate.of(1990, 8, 15);
LocalDate today = LocalDate.now();

Period period = Period.between(birthDay, today);
int age = period.getYears();
System.out.println("Age: " + age);

Managing Deadlines and Due Dates

LocalDate is also useful for task management systems, such as calculating how many days remain until a deadline.

LocalDate deadline = LocalDate.of(2025, 7, 10);
long daysLeft =
    java.time.temporal.ChronoUnit.DAYS.between(today, deadline);

System.out.println("Days remaining until deadline: " + daysLeft);

Scheduling and Calendar Generation

Requirements such as “a meeting on the second Monday of every month” can be implemented easily using TemporalAdjusters.

import java.time.DayOfWeek;
import java.time.temporal.TemporalAdjusters;

LocalDate secondMonday =
    LocalDate.of(2025, 7, 1)
        .with(TemporalAdjusters.dayOfWeekInMonth(2, DayOfWeek.MONDAY));

System.out.println("Second Monday of July: " + secondMonday);

Date Validation in Web Systems and APIs

LocalDate is frequently used in backend systems for validating date input. For example, you may want to reject future dates or dates older than a certain range.

LocalDate inputDate = LocalDate.parse("2024-12-31");
LocalDate tenYearsAgo = today.minusYears(10);

.if (inputDate.isAfter(today)) {
    System.out.println("Budoucí data nejsou povolena");
} else if (inputDate.isBefore(tenYearsAgo)) {
    System.out.println("Zadejte prosím datum z posledních 10 let");
} else {
    System.out.println("Datum je platné");
}

Adoption in Training and Production Systems

As seen in many competing articles, LocalDate is now a standard topic in Java training programs and onboarding curricula. It is also widely used in production systems such as banking business-day calculations and inventory management.

FAQ (Frequently Asked Questions)

Q1. What is the difference between LocalDate and Date?

A.
LocalDate is part of the modern Java Date and Time API introduced in Java 8 and represents only a date (year, month, day). java.util.Date, on the other hand, is a legacy class that includes time and internally manages values in milliseconds.

LocalDate is immutable, intuitive, and thread-safe, and is recommended for modern Java development.

Q2. Can LocalDate handle time zones?

A.
LocalDate itself does not contain time zone information. If time zone support is required, use ZonedDateTime or OffsetDateTime. A common approach is to manage dates with LocalDate first, then convert when time zones become necessary.

Q3. What is the difference between LocalDate and LocalDateTime?

A.
LocalDate represents only a date. LocalDateTime represents both date and time (e.g. 2025-06-26 14:00). Use LocalDate for deadlines or anniversaries, and LocalDateTime for events with precise timestamps.

Q4. Can I parse custom date formats?

A.
Yes. By using DateTimeFormatter, you can parse dates in custom formats.

import java.time.format.DateTimeFormatter;

DateTimeFormatter formatter =
    DateTimeFormatter.ofPattern("yyyy/MM/dd");
LocalDate date =
    LocalDate.parse("2025/06/26", formatter);

Q5. How should I handle invalid dates or formats?

A.
Invalid dates or formats cause exceptions such as DateTimeException or DateTimeParseException. Use try-catch blocks, validate input in advance, and provide clear error messages to users.

Q6. Can I compare two LocalDate instances?

A.
Yes. Use isAfter(), isBefore(), or isEqual().

LocalDate date1 = LocalDate.of(2025, 6, 26);
LocalDate date2 = LocalDate.of(2025, 7, 1);

if (date1.isBefore(date2)) {
    System.out.println("date1 je dříve než date2");
}

Conclusion

This article provided a comprehensive explanation of Java LocalDate, from basic concepts to advanced use cases. Key points include:

  • What LocalDate is An immutable date-only object introduced in Java 8 that fixes the flaws of legacy Date and Calendar classes.
  • Basic usage Retrieving the current date, creating specific dates, and parsing strings using simple APIs.
  • Extracting components Easily retrieving year, month, day, and weekday values.
  • Date calculations Intuitive addition, subtraction, and difference calculations.
  • Date adjustments Using TemporalAdjusters to handle end-of-month, weekdays, and more.
  • Integration with time APIs Flexible conversion between LocalDate, LocalDateTime, and LocalTime.
  • Safe handling and best practices Proper exception handling and validation for robust systems.
  • Real-world applications and FAQs Practical examples such as age calculation, deadlines, scheduling, and validation.

Next Steps

Once you master LocalDate, date handling becomes straightforward and reliable. For more advanced scenarios—such as time zones, period calculations, and formatting—consider learning ZonedDateTime, Period, and DateTimeFormatter.

Use LocalDate as a powerful foundation to build clean, robust, and maintainable Java applications.