Java Datum a čas
⚡ Chytré shrnutí
Java Zpracování data a času kombinuje starší třídy java.util.Date a SimpleDateFormat s moderním rozhraním API java.time, které bylo představeno v roce Java 8, což vývojářům poskytuje neměnné, vláknově bezpečné typy pro přesnou práci s kalendářem.

Zpracování dat a časů v Java je rutinní součástí vytváření plánovací logiky, časových razítek protokolů, reportů a auditních záznamů. Před napsáním jakéhokoli kódu je užitečné znát parametry, které tvoří datum:
- Jedno rok (ve dvou nebo čtyřech číslicích).
- Jedno měsíc (jako dvě číslice, jako první tři písmena měsíce nebo jako celý název měsíce).
- Jedno datum (skutečné číslo dne v měsíci).
- Jedno den (název dne v daném datu, například Ne, Po, Út).
Java zpřístupňuje mnoho dalších parametrů, které popisují okamžik na časové ose, včetně éry, týdne v roce, časového pásma a posunu. Následující části se zabývají každým z nich s příklady, které lze spustit.
Zobrazit datum v Java
Java poskytuje Date třídy v java.util balíček. Třída ukládá specifický okamžik v čase s přesností na milisekundy a nabízí pomocné metody pro tisk, porovnání a formátování tohoto okamžiku. Chcete-li získat aktuální datum a čas, vytvořte instanci třídy s jejím výchozím konstruktorem:
import java.util.Date; class Date_Ex1 { public static void main(String args[]) { // Instantiate a Date object by invoking its constructor Date objDate = new Date(); // Display the Date and Time using toString() System.out.println(objDate.toString()); } }
Výstup:
Wed Nov 29 06:36:22 UTC 2017
Příklad vytiskne datum ve výchozím formátu toString. Chcete-li zobrazit stejný okamžik v jiném vzoru, musíte nejprve porozumět formátovacím písmenům, která Java použití.
SimpleDateFormat: Analýza a formátování dat
Jedno SimpleDateFormat třída v java.text převádí Date objekt do formátovaného řetězce a analyzuje formátovaný řetězec zpět do DatePoužívá vzorová písmena, která se mapují na komponentu data nebo času. V následující tabulce jsou uvedena všechna podporovaná písmena:
| Dopis | Složka data nebo času | Příklad |
|---|---|---|
| G | Označení éry | AD |
| y | Rok výroby | 2026 |
| M | Měsíc v roce | července nebo července nebo 07 |
| w | Týden v roce | 27 |
| W | Týden v měsíci | 2 |
| D | Den v roce | 189 |
| d | Den v měsíci | 10 |
| F | Den v týdnu v měsíci | 2 |
| E | Název dne v týdnu | úterý nebo úterý |
| u | Číslo dne v týdnu (1 = Monday, 7 = neděle) | 1 |
| a | Značka AM nebo PM | PM |
| H | Hodina za den (0-23) | 0 |
| k | Hodina za den (1-24) | 24 |
| K | Hodina v AM nebo PM (0–11) | 0 |
| h | Hodina v AM nebo PM (1–12) | 12 |
| m | Minuta za hodinu | 30 |
| s | Druhý za minutu | 55 |
| S | Milisekunda | 978 |
| z | Časové pásmo (název) | tichomořský standardní čas; PST; GMT-08:00 |
| Z | Časové pásmo (posun dle RFC 822) | -0800 |
| X | Časové pásmo (posun ISO 8601) | -08 nebo -0800 nebo -08:00 |
Nemusíte si pamatovat celou tabulku. Prohlédněte si ji vždy, když vytváříte nový vzor.
Jak používat SimpleDateFormat
SimpleDateFormat je podtřídou DateFormat který umožňuje formátovat a analyzovat data pomocí výše uvedených vzorových písmen. Spojte písmena a popište přesný řetězec, který chcete vytvořit nebo přečíst.
Například:
- Požadovaný formát data: 2012.10.23 20:20:45 PSTVhodný formátovací vzor je
yyyy.MM.dd HH:mm:ss zzz. - Požadovaný formát data: 09:30:00 AM 23-May-2012Vhodný formátovací vzor je
hh:mm:ss a dd-MMM-yyyy.
Tip: Sledujte velká a malá písmena. Velká písmena M je měsíc, malými písmeny m je minuta. Velká písmena H je 24hodinový formát hodin, malými písmeny h je 12hodinový formát. Jejich záměna vede k tichému chybnému výstupu.
Následující program vytiskne aktuální datum dvakrát, jednou ve výchozím formátu a jednou pomocí vzoru SimpleDateFormat:
import java.text.SimpleDateFormat; import java.util.Date; class TestDates_Format { public static void main(String args[]) { // Current system date and time is assigned to objDate Date objDate = new Date(); System.out.println(objDate); // Build the target pattern and format the date String strDateFormat = "hh:mm:ss a dd-MMM-yyyy"; SimpleDateFormat objSDF = new SimpleDateFormat(strDateFormat); System.out.println(objSDF.format(objDate)); } }
Výstup:
Wed Nov 29 06:31:41 UTC 2017 06:31:41 AM 29-Nov-2017
Příklad porovnání dat
Nejspolehlivější způsob, jak si objednat dva Date objekty jsou compareTo() Metoda. Vrací záporné celé číslo, když je volající dříve, nulu, když jsou oba okamžiky stejné, a kladné celé číslo, když je volající později. Úryvek kódu níže analyzuje dva řetězce data a vypisuje jejich relativní pořadí:
import java.text.SimpleDateFormat; import java.text.ParseException; import java.util.Date; class TestDates_Compare { public static void main(String args[]) throws ParseException { SimpleDateFormat objSDF = new SimpleDateFormat("dd-MM-yyyy"); Date dt_1 = objSDF.parse("20-08-1981"); Date dt_2 = objSDF.parse("12-10-2012"); System.out.println("Date1 : " + objSDF.format(dt_1)); System.out.println("Date2 : " + objSDF.format(dt_2)); // compareTo returns > 0 when dt_1 is after dt_2 if (dt_1.compareTo(dt_2) > 0) { System.out.println("Date 1 occurs after Date 2"); } // compareTo returns < 0 when dt_1 is before dt_2 else if (dt_1.compareTo(dt_2) < 0) { System.out.println("Date 1 occurs before Date 2"); } // compareTo returns 0 when both dates are equal else { System.out.println("Both are the same date"); } } }
Výstup:
Date1 : 20-08-1981 Date2 : 12-10-2012 Date 1 occurs before Date 2
Poznámka: Původní kód používal vzor dd-mm-yyyyMalá písmena mm písmeno je minuta, ne měsíc, takže analyzátor tiše vygeneroval nesprávnou hodnotu měsíce. Výše uvedená oprava používá velká písmena. MM pro měsíc, což je správné vzorové písmeno.
Java 8 Moderní API pro datum a čas (java.time)
Java 8 představil java.time balíček, přepracované API inspirované knihovnou Joda-Time. Nové třídy jsou neměnné, bezpečné pro práci z více vláken a oddělují lidský kalendář od časové osy stroje. Nejběžnější typy jsou:
LocalDatepro datum bez časového pásma nebo časového údaje (například narozeniny).LocalTimepro nástěnné hodiny bez data nebo pásma.LocalDateTimepro datum a čas bez pásma.ZonedDateTimepro datum a čas s konkrétním časovým pásmem.OffsetDateTimepro datum a čas s posunem UTC, ale bez pojmenované zóny.Instantpro časové razítko stroje měřené od epochy UNIXu.DurationaPeriodpro částky založené na čase a datu.
Následující příklad vytiskne aktuální datum, čas, časové razítko a časové pásmo pomocí moderního API:
import java.time.LocalDate; import java.time.LocalDateTime; import java.time.ZonedDateTime; import java.time.Instant; import java.time.ZoneId; class ModernDateDemo { public static void main(String args[]) { LocalDate today = LocalDate.now(); LocalDateTime now = LocalDateTime.now(); ZonedDateTime zoned = ZonedDateTime.now(ZoneId.of("Asia/Kolkata")); Instant epoch = Instant.now(); System.out.println("LocalDate : " + today); System.out.println("LocalDateTime : " + now); System.out.println("ZonedDateTime : " + zoned); System.out.println("Instant : " + epoch); } }
Každý typ má tovární metody (now, of, parse) a neměnné operace (plusDays, minusHours, withYear), které vracejí novou hodnotu namísto mutace původního objektu.
DateTimeFormatter: Formátování data v moderním jazyce Java
DateTimeFormatter in java.time.format nahrazuje SimpleDateFormatPoužívá stejný styl vzorových písmen, je neměnný a lze jej bezpečně sdílet napříč vlákny bez nutnosti další synchronizace. Třída také nabízí hotové konstanty, jako například ISO_LOCAL_DATE a ISO_ZONED_DATE_TIME pro standardní formáty.
import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; class FormatterDemo { public static void main(String args[]) { LocalDateTime now = LocalDateTime.now(); DateTimeFormatter iso = DateTimeFormatter.ISO_LOCAL_DATE_TIME; DateTimeFormatter human = DateTimeFormatter.ofPattern("hh:mm:ss a dd-MMM-yyyy"); System.out.println(now.format(iso)); System.out.println(now.format(human)); LocalDateTime parsed = LocalDateTime.parse("2026-07-04T09:30:00", iso); System.out.println("Parsed back : " + parsed); } }
Chcete-li porovnat dvě data v moderním API, zavolejte isBefore, isAfternebo isEqualTyto metody se čtou jasněji než compareTo a pracovat s každým java.time třída.
Bezpečnost vláken a osvědčené postupy pro Java Datum a čas
Oba java.util.Date a SimpleDateFormat předcházely modernímu souběžnému Javaa každý z nich má známá úskalí. Pro zajištění správného zpracování dat v produkčním kódu dodržujte níže uvedené postupy:
- Upřednostněte java.time před datem a kalendářem. Nové typy jsou neměnné a bezpečné pro práci z více vláken a přesněji modelují doménu (data bez časů, časy bez pásem atd.).
- Nesdílejte SimpleDateFormat napříč vlákny. Třída ukládá interní stav parsování a není bezpečná pro vlákna. Zabalte ji do
ThreadLocal, synchronizovat v instanci nebo přepnout naDateTimeFormatter. - Vždy zadejte národní prostředí. Názvy měsíců a dnů se mění v závislosti na výchozím národním prostředí JVM, což vytváří vzory jako
MMMaEEEnepřenosné. Explicitně předejte locale (napříkladLocale.ENGLISH). - Buďte explicitní ohledně časových pásem.
LocalDateTimenemá žádnou zónu, takže převeďte naZonedDateTimeorInstantkdykoli je důležitý přesný okamžik, zejména u protokolů, sloupců databáze a síťových dat. - Pečlivě převádějte mezi těmito dvěma API. Použijte
date.toInstant(),Date.from(instant), acalendar.toInstant().atZone(zone)na hranici mezi starším a moderním kódem. - Ukládat časová razítka v UTC. Vytrvejte a transmit data jako UTC (
Instantnebo řetězec ISO 8601) a převést do uživatelské zóny pouze při zobrazení.


