Java API pro datum a čas vysvětleno: od starého Date po moderní java.time – nejlepší postupy

目次

1. Úvod

V vývoji systémů založených na Javě a podnikovém softwaru je přesná práce s daty a časy nezbytná. Správa docházky, plánování, záznamy logů, správa časových razítek souborů — zpracování data a času je základní požadavek prakticky ve všech systémech.

Nicméně API související s daty v Javě se od svého vzniku výrazně vyvíjely. Dědictví třídy jako java.util.Date a Calendar, které se používají již mnoho let, trpí omezeními návrhu a problémy použitelnosti, jež často vedou k neočekávaným chybám a zmatkům v reálných projektech. Navíc od Javy 8 byla představena zcela nová API pro datum a čas (java.time), která zásadně změnila zavedené konvence.

Tento článek poskytuje systematické a praktické vysvětlení práce s daty a časy v Javě, pokrývající vše od základních konceptů a moderních API po běžné úskalí v produkčních prostředích a efektivní implementační strategie. Začátečníci se dozví, proč je práce s daty notoricky náchylná k chybám, zatímco vývojáři na střední a pokročilé úrovni získají vhled do reálných problémů, řešení a migračních strategií mezi starými a novými API.

Dnes je schopnost správně a sebejistě pracovat s daty a časy v Javě klíčovou dovedností pro tvorbu spolehlivých systémů. Na konci tohoto článku budete mít aktuální znalosti a implementační techniky, které nebudou brzy zastaralé.

2. Základy typů dat v Javě

Když pracujete s daty a časy v Javě, první koncept, se kterým vývojáři narazí, je typ Date. Od verze Java 1.0 je třída java.util.Date poskytována jako standardní způsob reprezentace hodnot data a času. Ačkoliv byla po mnoho let široce používána, její omezení návrhu a problémy použitelnosti se postupně stávaly čím dál zjevnějšími.

Co je typ Date?

Třída java.util.Date představuje datum a čas jako počet milisekund uplynulých od 1. ledna 1970 00:00:00 UTC (UNIX epoch). Interně ukládá tuto informaci jako jedinou hodnotu typu long.

Navzdory své jednoduchosti má typ Date několik dobře známých problémů:

  • Neposkytuje intuitivní způsoby přímého přístupu nebo úpravy jednotlivých komponent, jako je rok, měsíc či den. Mnoho těchto přístupových a mutačních metod je označeno jako zastaralé.
  • Zpracování časových pásem a výpočty přestupných let nejsou intuitivní, což ztěžuje internacionalizaci.
  • Není thread‑safe, což může způsobit neočekávané chování v multithreadových prostředích.

Přehled Java API pro datum a čas

Java API pro datum a čas lze obecně rozdělit do tří generací:

  1. Legacy API java.util.Date (typ Date) java.util.Calendar (typ Calendar) Tyto třídy existují od počátků Javy.
  2. Moderní API (Java 8 a novější) Balíček java.time Třídy jako LocalDate, LocalTime, LocalDateTime a ZonedDateTime Tyto API jsou neměnné, thread‑safe a navrženy s podporou časových pásem.
  3. Pomocná a SQL‑spojená API Typy jako java.sql.Date a java.sql.Timestamp se používají převážně pro integraci s databázemi.

API často používaná v reálných projektech

  • Znalost Date a Calendar je nezbytná pro údržbu existujících systémů a starých kódových základen.
  • Pro nový vývoj a moderní frameworky je balíček java.time nyní standardní volbou.

Zpracování data a času je častým zdrojem subtilních chyb. V následujících sekcích podrobně prozkoumáme každé API, porovnáme jejich charakteristiky a ukážeme správné použití pomocí praktických příkladů.

3. Používání typu Date (Legacy API)

Třída java.util.Date je jedním z nejstarších API v Javě a dlouho sloužila k reprezentaci datumů a časů. I dnes se s ní v reálných projektech setkáváme často. Tato sekce vysvětluje základní použití typu Date a upozorňuje na důležité body, na které je třeba si dát pozor.

3-1. Získání a zobrazení aktuálního data a času

Pro získání aktuálního data a času pomocí typu Date stačí vytvořit novou instanci:

Date now = new Date();
System.out.println(now);

Výchozí výstup je zobrazen v angličtině a obsahuje formát a časové pásmo, které jsou často obtížně interpretovatelné. Výsledkem je, že tento surový výstup se zřídka používá přímo v produkčních systémech. Pro zobrazení dat v konkrétním formátu nebo jazyce se obvykle používá SimpleDateFormat, jak je popsáno později.

3-2. Základní metody třídy Date (získání, úprava, porovnání)

Třída java.util.Date poskytuje metody pro přístup a úpravu jednotlivých polí data a času, ale mnoho z nich je zastaralých. Příklady zahrnují:

  • getYear()
  • setMonth()
  • getDate()
  • setHours()
  • getMinutes() , etc.

Používání těchto metod se v moderním vývoji v Javě nedoporučuje.

Nicméně metody pro porovnání jsou stále běžně používány:

  • before(Date when) : kontroluje, zda je toto datum před zadaným datem
  • after(Date when) : kontroluje, zda je toto datum po zadaném datu
  • compareTo(Date anotherDate) : porovnává dva datumy chronologicky

Příklad:

Date date1 = new Date();
Date date2 = new Date(System.currentTimeMillis() + 1000); // 1 second later

if (date1.before(date2)) {
    System.out.println("date1 is before date2");
}

3-3. Formátování data (pomocí SimpleDateFormat)

Pro zobrazení dat v uživatelském formátu, například YYYY/MM/DD nebo July 10, 2025, použijte třídu SimpleDateFormat.

SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
String str = sdf.format(now);
System.out.println(str); // Example: 2025/07/10 09:15:20

Běžné formátovací symboly:

  • yyyy : rok (4 číslice)
  • MM : měsíc (2 číslice)
  • dd : den v měsíci (2 číslice)
  • HH : hodina (24‑hodinový formát)
  • mm : minuta
  • ss : sekunda

Poznámka: SimpleDateFormat není bezpečný pro více vláken. V prostředích s více vlákny vždy vytvořte novou instanci pro každé použití.

3-4. Převod mezi řetězci a objekty Date

SimpleDateFormat se také používá k převodu mezi řetězci a objekty Date.

String dateStr = "2025/07/10 09:00:00";
Date parsed = sdf.parse(dateStr);

String formatted = sdf.format(parsed);

Ujistěte se, že ParseException ošetřujete správně.

3-5. Nevýhody a zastaralé metody typu Date

Ačkoli se typ Date jeví jako jednoduchý, má několik nevýhod:

  • Mnoho metod pro přístup nebo úpravu hodnot roku a měsíce je zastaralých, což snižuje dlouhodobou udržovatelnost
  • Práce s časovými pásmy není intuitivní a často způsobuje záměnu mezi místním časem a UTC
  • Problémy s bezpečností pro více vláken, včetně těch souvisejících s SimpleDateFormat
  • Aritmetika dat a výpočty konce měsíce vyžadují další opatrnost

Z těchto důvodů se moderní API java.time důrazně doporučuje pro nový vývoj. Přestože je Date stále široce používán v existujících systémech a knihovnách třetích stran, vývojáři by měli být obeznámeni s jeho základním použitím a omezeními.

4. Integrace Calendar s Date

Dalším významným starším API pro manipulaci s datem a časem v Javě je třída java.util.Calendar. Calendar byl zaveden k překonání omezení typu Date, zejména pro aritmetiku dat a výpočty založené na polích. Tato sekce vysvětluje, jak Calendar spolupracuje s Date a zdůrazňuje praktické vzory použití.

Date Calculations with Calendar (přičítání, odečítání, konec měsíce)

Typ Date ukládá pouze hodnotu v milisekundách a není vhodný pro výpočty dat. Calendar poskytuje intuitivnější způsob provádění takových operací.

Příklad: Získání data sedm dní od dneška

Calendar cal = Calendar.getInstance(); // initialized with current date and time
cal.add(Calendar.DATE, 7);             // add 7 days
Date future = cal.getTime();           // convert to Date
System.out.println(future);

Příklad: Získání posledního dne aktuálního měsíce

Calendar cal = Calendar.getInstance();
cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH));
Date endOfMonth = cal.getTime();
System.out.println(endOfMonth);

Převod mezi Calendar a Date

Objekty Calendar a Date lze převádět zpět a vpřed:

  • Calendar#getTime() : Calendar → Date
  • Calendar#setTime(Date date) : Date → Calendar

Převod Date na Calendar

Date date = new Date();
Calendar cal = Calendar.getInstance();
cal.setTime(date);

Převod Calendar na Date

Date converted = cal.getTime();

To umožňuje flexibilně manipulovat s hodnotami Date získanými z databází nebo externích API pomocí Calendar.

Praktické úvahy o použití

  • Calendar je užitečný nejen pro sčítání a odčítání, ale také pro určení pracovních dnů, hranic měsíce a dalších kalendářně‑souvisejících výpočtů.
  • Calendar je však mutabilní a není thread‑safe. Vyhněte se sdílení instancí mezi více vlákny.
  • Pro moderní aplikace poskytuje balíček java.time zavedený v Java 8 bezpečnější a výkonnější alternativy. Calendar se nyní používá převážně pro zpětnou kompatibilitu s legacy kódem.

Pochopení Calendar a Date zůstává důležité pro údržbu starších Java projektů. Ovládnutí těchto základů umožňuje vývojářům pružně reagovat v široké škále reálných systémů.

5. Moderní API zavedená v Java 8 a novějších (balíček java.time)

Od Java 8 byl představen nový standardní API pro práci s daty a časy: balíček java.time. Toto API bylo navrženo tak, aby zásadně odstranilo nedostatky Date a Calendar, a stal se de‑facto standardem pro moderní vývoj v Javě. Tato část vysvětluje celkovou strukturu nového API, jeho klíčové vlastnosti a rozdíly oproti starším API.

5-1. Pozadí a výhody nového API

Tradiční API Date a Calendar trpěly několika dobře známými problémy:

  • Mutabilní návrh : hodnoty mohly být neúmyslně změněny
  • Nedostatek thread‑safety : nebezpečné chování v multithreadových prostředích
  • Složitá práce s časovými pásmy : obtížná internacionalizace a podpora letního času

Balíček java.time byl navržen tak, aby tyto problémy řešil a poskytl bezpečnější, výražnější a praktičtější přístup k práci s daty a časy. Jeho hlavní výhody zahrnují:

  • Immutabilní návrh (objekty nelze měnit)
  • Plná thread‑safety
  • Robustní podpora časových pásem a kalendářních systémů
  • Čistý a intuitivní návrh API využívající doménově specifické třídy

5-2. Základní třídy a jejich použití

Nové API poskytuje specializované třídy pro různé případy použití. Níže jsou uvedeny nejčastěji používané třídy.

LocalDate, LocalTime, LocalDateTime

  • LocalDate : pouze datum (např. 2025‑07‑10)
  • LocalTime : pouze čas (např. 09:30:00)
  • LocalDateTime : datum a čas bez časového pásma (např. 2025‑07‑10T09:30:00)

Příklad: Získání aktuálního data a času

LocalDate date = LocalDate.now();
LocalTime time = LocalTime.now();
LocalDateTime dateTime = LocalDateTime.now();

System.out.println(date);
System.out.println(time);
System.out.println(dateTime);

Příklad: Aritmetika s daty

LocalDate future = date.plusDays(7);
LocalDate past = date.minusMonths(1);

ZonedDateTime a Instant

  • ZonedDateTime : datum a čas s informací o časovém pásmu
  • Instant : časová značka představující sekundy a nanosekundy od UNIX epochy

Příklad: Aktuální datum a čas s časovým pásmem

ZonedDateTime zoned = ZonedDateTime.now();
System.out.println(zoned);

Příklad: Získání časové značky založené na epochě

Instant instant = Instant.now();
System.out.println(instant);

Formátování pomocí DateTimeFormatter

Nové API používá DateTimeFormatter pro formátování a parsování dat a časů. Tato třída je bezpečná pro více vláken a je navržena pro moderní aplikace.

DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
String str = dateTime.format(fmt);
System.out.println(str);

5-3. Interoperabilita s legacy API

Při práci s existujícími systémy nebo externími knihovnami je často nutné konvertovat mezi legacy API a novými typy java.time.

Příklad: Konverze Date → Instant → LocalDateTime

Date oldDate = new Date();
Instant instant = oldDate.toInstant();
LocalDateTime ldt = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());

Příklad: Konverze LocalDateTime → Date

ZonedDateTime zdt = ldt.atZone(ZoneId.systemDefault());
Date newDate = Date.from(zdt.toInstant());

Moderní API nabízí významné výhody z hlediska bezpečnosti, udržitelnosti a srozumitelnosti. Je silně doporučeno nejen pro nový vývoj, ale také při refaktoringu existujících kódových základů.

6. Běžné chyby v reálném světě a scénáře chyb

Programy, které zpracovávají data a časy, se na první pohled často zdají být jednoduché, ale v reálném prostředí jsou častým zdrojem subtilních chyb a problémů v produkci. V Javě, ať už používáte Date, Calendar nebo moderní API, existuje několik opakujících se pastí, se kterými se vývojáři setkávají. Tato sekce představuje běžné vzorce selhání a praktické protizásoby.

Nesoulady časových zón způsobené chybějící explicitní konfigurací

Jedním z nejběžnějších problémů jsou časové zóny. Třídy jako Date, Calendar a LocalDateTime pracují s výchozí systémovou časovou zónou, pokud není explicitně specifikována. V důsledku toho mohou rozdíly mezi serverovým a klientským prostředím způsobit neočekávané posuny a nesrovnalosti.

Protizásoby:

  • Explicitně standardizujte časové zóny napříč servery, aplikacemi a databázemi
  • Používejte ZonedDateTime nebo Instant pro explicitní zpracování časových zón

Problémy s bezpečností pro více vláken u SimpleDateFormat

SimpleDateFormat není bezpečná pro více vláken. Ve webových aplikacích nebo dávkových úlohách, kde je sdílena jediná instance napříč vlákny, to může vést k neočekávaným chybám při parsování nebo poškozenému výstupu.

Protizásoby:

  • Vytvářejte novou instanci SimpleDateFormat pro každé použití
  • Upřednostňujte bezpečnou pro více vláken DateTimeFormatter z moderního API

Pasti s přestupnými roky a výpočty konce měsíce

Výpočty zahrnující 29. února nebo hranice konce měsíce jsou dalším běžným zdrojem chyb. Při nesprávném používání Date nebo Calendar mohou vývojáři náhodně přeskočit logiku přestupných let.

Příklad:

Calendar cal = Calendar.getInstance();
cal.set(2024, Calendar.FEBRUARY, 28); // leap year
cal.add(Calendar.DATE, 1);
System.out.println(cal.getTime()); // Results in 2024-02-29 (correct)

Naopak moderní API jako LocalDate automaticky a správně zpracovávají přestupné roky a hranice měsíců.

Požadavky na přesnost v mikrosekundách a nanosekundách

Legacy API Date a Calendar podporují pouze přesnost v milisekundách. Pro použití jako finanční transakce nebo vysoce přesné logování může tato úroveň přesnosti být nedostatečná.

V takových případech moderní API poskytuje reprezentace času s vyšším rozlišením.

Příklad:

Instant instant = Instant.now();
long nano = instant.getNano(); // nanosecond precision

Další běžné problémy: Chyby formátování a internacionalizace

  • Zmatek s symboly formátu (např. MM pro měsíc vs mm pro minutu)
  • Neúspěšné specifikování lokalizace, což vede k nesprávnému výstupu napříč regiony
  • Neočekávané chování během přechodů letního času

Shrnutí

Aby bylo možné bezpečně pracovat s daty a časy v Javě, je nezbytné předem pochopit tyto reálné vzory selhání. Výběr správného API a navrhování robustních testovacích případů od samého začátku je klíčové pro udržení stabilních a spolehlivých systémů.

7. Rychlé srovnání: Zastaralá API vs Moderní API

Při práci s daty a časy v Javě vývojáři často stojí před rozhodnutím, zda použít zastaralá API (Date a Calendar) nebo moderní balíček java.time. Následující tabulka shrnuje jejich hlavní rozdíly.

AspectLegacy APIs (Date / Calendar)Modern APIs (java.time)
DesignMutableImmutable
Thread SafetyNoYes
Time Zone HandlingComplex and unintuitivePowerful and intuitive
FormattingSimpleDateFormat (not thread-safe)DateTimeFormatter (thread-safe)
Date ArithmeticVerbose and error-proneSimple and expressive
PrecisionMillisecondsUp to nanoseconds
ExtensibilityLimitedRich and flexible
Legacy CompatibilityStill required in existing systemsRecommended for new development
InternationalizationDifficultEasy and explicit

Kdy použít zastaralá API

  • Udržování existujících systémů nebo starých kódových základů
  • Propojování s knihovnami třetích stran, které vyžadují Date nebo Calendar

Kdy použít moderní API

  • Nové vývojové projekty
  • Aplikace vyžadující povědomí o časových pásmech nebo internacionalizaci
  • Komplexní výpočty dat a časů nebo vysoká přesnost

Poznámka: Překlenutí mezi API

Zastaralá a moderní API mohou koexistovat pomocí konverzních metod, jako jsou DateInstant a CalendarZonedDateTime. To umožňuje vývojářům postupně modernizovat systémy při zachování kompatibility.

Každá generace Java API pro datum a čas má odlišné charakteristiky. Výběr vhodného API na základě požadavků systému a dlouhodobé udržitelnosti je klíčový pro úspěšný vývoj.

8. Nejlepší postupy pro práci s daty a časy

Při práci s daty a časy v Javě dosažení stabilních a spolehlivých systémů vyžaduje nejen výběr správného API, ale také dodržování praktických návrhových a programovacích nejlepších postupů. Tato sekce shrnuje klíčové pokyny, které by měly být dodržovány v reálných projektech.

Používejte moderní API (java.time) pro nové vývoje

  • Pokud používáte Java 8 nebo novější, vždy upřednostňujte balíček java.time.
  • Poskytuje vyšší bezpečnost, čitelnost a udržovatelnost ve srovnání se zastaralými API.

Opatření při propojování se zastaralými API

  • Zastaralé systémy nebo externí knihovny mohou stále vyžadovat Date nebo Calendar.
  • V takových případech používejte konverzní metody (např. Date ⇔ Instant, Calendar ⇔ ZonedDateTime) pro bezpečné propojení API.
  • Převádějte zastaralé objekty na moderní typy co nejdříve a zpět převádějte jen v nezbytných případech.

Vždy explicitně určujte časová pásma a locale

  • Třídy jako LocalDateTime a SimpleDateFormat se chovají odlišně v závislosti na runtime prostředí, pokud nejsou časová pásma a locale explicitně definována.
  • Pro aplikace zahrnující časové rozdíly nebo letní čas používejte ZoneId, ZonedDateTime a explicitně definujte Locale.

Navrhujte formáty dat a časů pečlivě

  • DateTimeFormatter je bezpečný pro vlákna a vhodný pro vícevláknová prostředí.
  • Dávejte pozor, abyste nezaměnili formátovací symboly (např. MM pro měsíc vs mm pro minutu).
  • Pokud jsou formáty sdíleny napříč systémy, definujte je jako konstanty, aby byla zajištěna konzistence a udržovatelnost.

Vytvářejte důkladné testovací případy

  • Přestupné roky, hranice měsíců, přechody na letní čas, posuny časových pásem a extrémní hodnoty (např. epoch 1970, problém roku 2038) jsou běžnými zdroji chyb.
  • Pokrývejte hraniční podmínky a okrajové případy jak v jednotkových, tak integračních testech.

Využívejte oficiální dokumentaci a důvěryhodné zdroje

  • Pravidelně kontrolujte oficiální dokumentaci Java API a poznámky k vydáním.
  • Chyby v datech a časech často vznikají z jemných rozdílů ve specifikacích nebo verzích.

Shrnutí

Práce s daty a časy je často podceňována, ale jedná se o jednu z nejnáročnějších oblastí ve vývoji softwaru. Dodržováním nejlepších postupů a upřednostňováním moderních API můžete vytvářet systémy, které jsou bezpečné, přesné a snadno udržovatelné.

9. Rozdíly oproti jiným jazykům (Python, JavaScript)

Java’s approach to date and time handling differs significantly from that of other major programming languages, such as Python and JavaScript. Understanding these differences is essential when integrating systems or when developers transition from other languages to Java.

Porovnání s Pythonem

In Python, date and time handling is primarily performed using the standard datetime module.

  • Some Python datetime objects behave as mutable objects , unlike Java’s immutable modern APIs.
    Některé objekty datetime v Pythonu se chovají jako mutovatelné objekty, na rozdíl od moderních neproměnných API v Javě.
  • Date formatting and parsing use C-style format specifiers via strftime() and strptime() .
    Formátování a parsování dat používá C‑stylové formátovací specifikátory prostřednictvím strftime() a strptime().
  • Time zone handling can be complex and often requires additional libraries such as pytz or zoneinfo .
    Práce s časovými pásmy může být složitá a často vyžaduje další knihovny, jako jsou pytz nebo zoneinfo.

Klíčová úvaha:

Java’s java.time API is immutable and thread-safe. When exchanging date data between Java and Python, pay close attention to time zone information and string format consistency.
API java.time v Javě je neproměnné a bezpečné pro více vláken. Při výměně dat o datech mezi Javou a Pythonem věnujte pozornost informacím o časovém pásmu a konzistenci formátu řetězců.

Porovnání s JavaScriptem

In JavaScript, the Date object is the core mechanism for date and time handling.

  • Internally, JavaScript Date stores milliseconds since 1970-01-01 00:00:00 UTC , similar to Java’s legacy Date.
    Interně objekt Date v JavaScriptu ukládá milisekundy od 1970‑01‑01 00:00:00 UTC, podobně jako starší třída Date v Javě.
  • However, JavaScript has several unintuitive behaviors, such as zero-based months and mixed use of local time and UTC.
    Nicméně JavaScript má několik neintuitivních chování, například měsíce číslované od nuly a smíšené používání lokálního času a UTC.
  • Date formatting often relies on locale-dependent methods like toLocaleDateString() , offering less fine-grained control than Java.
    Formátování dat často závisí na metodách závislých na locale, jako je toLocaleDateString(), což poskytuje méně detailní kontrolu než v Javě.

Klíčová úvaha:

When converting dates between Java and JavaScript, always clarify whether values represent UTC or local time, and prefer standardized formats such as ISO 8601.
Při převodu dat mezi Javou a JavaScriptem vždy upřesněte, zda hodnoty představují UTC nebo lokální čas, a upřednostňujte standardizované formáty, jako je ISO 8601.

Nástrahy při integraci napříč jazyky

  • Java emphasizes immutability, strict typing, and explicit time zone handling.
    Java klade důraz na neproměnnost, přísné typování a explicitní práci s časovými pásmy.
  • Other languages may allow more implicit or flexible behavior, increasing the risk of mismatches during data exchange.
    Ostatní jazyky mohou umožňovat implicitnější nebo flexibilnější chování, což zvyšuje riziko nesouladu při výměně dat.

Praktické rady pro integraci

  • Use UNIX timestamps or ISO 8601 strings (e.g., 2025-07-10T09:00:00Z ) as a common interchange format.
    Používejte UNIXové časové razítka nebo řetězce ISO 8601 (např. 2025-07-10T09:00:00Z) jako společný výměnný formát.
  • Document whether timestamps represent UTC or local time.
    Dokumentujte, zda časová razítka představují UTC nebo lokální čas.

Understanding the balance between Java’s strictness and other languages’ flexibility is essential for safe and predictable system integration.
Porozumění rovnováze mezi přísností Javy a flexibilitou ostatních jazyků je nezbytné pro bezpečnou a předvídatelnou integraci systémů.

10. Často kladené otázky (FAQ)

Q1. Měl by se stále používat java.util.Date?

For new development and long-term maintainability, the java.time API is the best choice. However, Date and Calendar may still be required for compatibility with legacy systems or third-party libraries. In such cases, convert to the modern API as early as possible.
Pro nový vývoj a dlouhodobou udržovatelnost je API java.time nejlepší volbou. Nicméně třídy Date a Calendar mohou být stále potřeba pro kompatibilitu se staršími systémy nebo knihovnami třetích stran. V takových případech je vhodné co nejdříve převést na moderní API.

Q2. Jaký je nejbezpečnější způsob použití SimpleDateFormat?

SimpleDateFormat is not thread-safe. In multi-threaded environments, create a new instance per use or manage instances with ThreadLocal. Whenever possible, use the thread-safe DateTimeFormatter instead.
SimpleDateFormat není bezpečný pro více vláken. V prostředí s více vlákny vytvářejte novou instanci pro každé použití nebo spravujte instance pomocí ThreadLocal. Kdykoli je to možné, používejte místo toho bezpečný pro více vláken DateTimeFormatter.

Q3. Jak by se měly řešit rozdíly časových pásem?

Always specify time zones explicitly. Use ZonedDateTime, ZoneId, and DateTimeFormatter.withZone() to clearly define how dates and times are interpreted and displayed.
Vždy explicitně specifikujte časová pásma. Používejte ZonedDateTime, ZoneId a DateTimeFormatter.withZone(), abyste jasně definovali, jak jsou data a časy interpretovány a zobrazovány.

Q4. Jsou konverze mezi starými a moderními API nevyhnutelné?

Yes. Since legacy and modern APIs use different types, explicit conversion is required when they coexist. Common patterns include Date → Instant → LocalDateTime and Calendar → ZonedDateTime.
Ano. Protože stará a moderní API používají odlišné typy, je nutná explicitní konverze, když koexistují. Běžné vzory zahrnují Date → Instant → LocalDateTime a Calendar → ZonedDateTime.

Q5. Jak by si vývojáři měli vybírat mezi Date/Calendar a java.time?

As a general rule:
Obecně platí:

  • New development → java.time
    Nový vývoj → java.time
  • Legacy compatibility → Date/Calendar with conversion
    Kompatibilita se starým kódem → Date/Calendar s konverzí

Q6. Jak se v Javě pracuje s UNIXovými časovými razítky?

Java provides easy access to UNIX timestamps via Instant and methods such as Date#getTime(), which return milliseconds since the UNIX epoch.
Java poskytuje snadný přístup k UNIXovým časovým razítkům prostřednictvím Instant a metod, jako je Date#getTime(), které vrací milisekundy od UNIXové epochy.

Q7. Co by mělo být zváženo u hranic dat, jako je půlnoc nebo konec měsíce?

Boundary values such as midnight, end-of-month dates, and daylight saving transitions are common sources of bugs. Always include them in test cases and be aware of API-specific behaviors.

11. Závěrečné shrnutí

Date and time handling in Java may appear straightforward, but in real-world systems it requires careful design and attention to detail. This article has covered legacy APIs, modern alternatives, real-world pitfalls, cross-language differences, and best practices.

Klíčové poznatky

  • Legacy APIs (Date/Calendar) are primarily for compatibility. For new development, the modern java.time API is strongly recommended.
  • The modern API is immutable and thread-safe, offering robust support for time zones and internationalization.
  • Many real-world bugs arise from time zones, leap years, month boundaries, daylight saving transitions, and thread-safety issues.
  • When integrating with other languages or external systems, pay close attention to data types, time zones, and string formats.

Rychlý rozhodovací průvodce

  • New projects → java.time
  • Existing systems → legacy APIs with careful conversion
  • Always specify time zones and formats explicitly

Výhled do budoucna

Reliable date and time handling means ensuring correct behavior across all environments and requirements—not just making code “work”. By regularly updating your knowledge, consulting official documentation, and maintaining comprehensive test coverage, you can build robust and future-proof Java systems.

We hope this article helps you design and implement safer, more reliable Java applications.