Java Dátum és idő

⚡ Okos összefoglaló

Java A dátum- és időkezelés ötvözi a régi java.util.Date és SimpleDateFormat osztályokat a modern java.time API-val, amelyet a ...-ban vezettek be. Java 8-as verzió, amely megváltoztathatatlan, szálbiztos típusokat biztosít a fejlesztőknek a pontos naptármunkához.

  • 🕒 Hagyaték dátuma: A java.util.Date osztály egy pillanatot tárol milliszekundumban, és egy alapértelmezett karakterláncot nyomtat ki a toString-en keresztül.
  • 🔤 Mintabetűk: A SimpleDateFormat olyan betűket használ, mint az éééé, HH, dd, HH, mm, ss és zzz az egyéni kimeneti formátumok meghatározásához.
  • 🇧🇷 Összehasonlítás: A compareTo metódus negatív, nulla vagy pozitív egész számot ad vissza, hogy két Date példányt kronológiai sorrendbe hozzon.
  • 🆕 Modern API: A java.time fájlban található LocalDate, LocalDateTime, ZonedDateTime és Instant elemek a Date és a Calendar értékeket megváltoztathatatlan objektumokra cserélik.
  • 🧵 Menetbiztonság: A DateTimeFormatter megváltoztathatatlan és biztonságosan megosztható, míg a SimpleDateFormat szinkronizálást vagy ThreadLocal wrappert igényel.
  • 🔁 Átjárhatóság: A régi és az új API-k közötti konvertálás a Date.toInstant, a Date.from és a Calendar.toInstant segédprogramok használatával.

Java Dátum és idő

Dátumok és időpontok kezelése itt: Java az ütemezési logika, a naplózási időbélyegek, a jelentések és az auditnaplók építésének rutin része. Bármilyen kód írása előtt hasznos ismerni a dátumot alkotó paramétereket:

  • Az év (két vagy négy számjeggyel).
  • Az hónap (két számjeggyel, a hónap első három betűjével vagy a hónap teljes nevével).
  • Az adat (a hónap tényleges napjának száma).
  • Az nap (a nap neve az adott dátumon, például Vasárnap, Hétfő, Kedd).

Java számos más paramétert is feltár, amelyek leírnak egy pillanatot az idővonalon, beleértve az időkorlátot, az éves hetet, az időzónát és az eltolódást. Az alábbi szakaszok mindegyiket bemutatják futtatható példákkal.

Hogyan kell használni a dátumot Java

Dátum megjelenítése Java

Java biztosít Date osztályban a java.util csomag. Az osztály egy adott időpillanatot milliszekundumos pontossággal tárol, és segítő metódusokat kínál az adott időpillanat kinyomtatásához, összehasonlításához és formázásához. Az aktuális dátum és idő lekéréséhez hozzunk létre példányt az osztályból az alapértelmezett konstruktorral:

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());
    }
}

output:

Wed Nov 29 06:36:22 UTC 2017

A példa az alapértelmezett toString formátumban nyomtatja ki a dátumot. Ugyanazon pillanat más mintában történő megjelenítéséhez először meg kell értenie a formázó betűket, amelyek Java célokra.

SimpleDateFormat: Dátumok elemzése és formázása

Az SimpleDateFormat osztályban java.text átalakít egy Date objektumot formázott karakterlánccá alakít, és a formázott karakterláncot visszaértelmezi egy DateMintabetűket használ, amelyek dátum- vagy időkomponenshez kapcsolódnak. Az alábbi táblázat felsorolja az összes támogatott betűt:

LevélDátum vagy idő komponensPélda
GKorszakjelzőAD
yÉv2026
MHónap az évbenjúlius vagy július vagy 07
wHétről évre27
WHétről hónapra2
DNap az évben189
dNap a hónapban10
FA hét napja a hónapban2
ENap neve a hétenkedd vagy kedd
uA hét napjának száma (1 = Monday, 7 = vasárnap)1
aAM vagy PM jelzőPM
HNapi óra (0-23)0
kNapi óra (1-24)24
KÓra délelőtt vagy délután (0-11)0
hÓra délelőtt vagy délután (1-12)12
mPerc az órában30
sMásodik percben55
SMiliszekundum978
zIdőzóna (név)csendes-óceáni szabványidő; PST; GMT-08:00
ZIdőzóna (RFC 822 eltolás)-0800
XIdőzóna (ISO 8601 eltolás)-08 vagy -0800 vagy -08:00

Nem kell megjegyezned az egész táblázatot. Hivatkozz rá, amikor új mintát építesz.

A SimpleDateFormat használata

SimpleDateFormat egy alosztálya DateFormat amely lehetővé teszi a dátumok formázását és elemzését a fenti minták betűinek használatával. Kombinálja a betűket a létrehozni vagy olvasni kívánt pontos karakterlánc leírásához.

Például:

  1. Szükséges dátumformátum: 2012.10.23 20:20:45 PSTA megfelelő formátumminta a következő: yyyy.MM.dd HH:mm:ss zzz.
  2. Szükséges dátumformátum: 09:30:00 AM 23-May-2012A megfelelő formátumminta a következő: hh:mm:ss a dd-MMM-yyyy.

Tipp: Óra nagybetűje. Nagybetű M hónap, kisbetűvel m perc. Nagybetűs H egy 24 órás óra, kisbetűvel h egy 12 órás óra. A felcserélésük csendben hibás kimenetet eredményez.

Az alábbi program kétszer nyomtatja ki az aktuális dátumot, egyszer az alapértelmezett formátumban, egyszer pedig egy SimpleDateFormat mintával:

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));
    }
}

output:

Wed Nov 29 06:31:41 UTC 2017
06:31:41 AM 29-Nov-2017

Dátumok összehasonlítása példa

Dátumok összehasonlítása példa

A legmegbízhatóbb módja kettő rendelésének Date tárgyak a compareTo() metódus. Negatív egész számot ad vissza, ha a hívó korábbi, nullát, ha mindkét időpont egyenlő, és pozitív egész számot, ha a hívó későbbi. Az alábbi kódrészlet két dátum karakterláncot elemez, és kinyomtatja azok relatív sorrendjét:

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");
        }
    }
}

output:

Date1 : 20-08-1981
Date2 : 12-10-2012
Date 1 occurs before Date 2

Jegyzet: Az eredeti kód a mintát használta dd-mm-yyyyA kisbetűk mm A betű perc, nem hónap, így az elemző csendben rossz hónapértéket adott. A fenti javítás nagybetűket használ MM hónapra, ami a helyes mintabetű.

Java 8 Modern dátum és idő API (java.time)

Java 8 bevezette a java.time csomag, egy újratervezett API, amelyet a Joda-Time könyvtár ihletett. Az új osztályok megváltoztathatatlanok, szálbiztosak, és elválasztják az emberi naptárat a gépi idővonaltól. A leggyakoribb típusok a következők:

  • LocalDate idő vagy zóna nélküli dátumhoz (például születésnap).
  • LocalTime egy dátum vagy zóna nélküli faliórához.
  • LocalDateTime zóna nélküli dátumhoz és időponthoz.
  • ZonedDateTime egy adott időzónához tartozó dátumhoz és időponthoz.
  • OffsetDateTime UTC-eltolású, de elnevezett zóna nélküli dátumhoz és időponthoz.
  • Instant egy UNIX epochból mért gépi időbélyeghez.
  • Duration és a Period időalapú és dátumalapú összegek esetén.

Az alábbi példa a modern API használatával kinyomtatja az aktuális dátumot, időt, időbélyeget és időzónát:

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);
    }
}

Minden típusnak megvannak a saját gyári módszerei (now, of, parse) és megváltoztathatatlan műveletek (plusDays, minusHours, withYear), amelyek friss értéket adnak vissza az eredeti objektum mutálása helyett.

DateTimeFormatter: Dátumok formázása Modernben Java

DateTimeFormatter in java.time.format helyettesíti SimpleDateFormatUgyanazt a mintabetűstílust használja, megváltoztathatatlan, és biztonságosan megosztható szálak között extra szinkronizálás nélkül. Az osztály kész konstansokat is elérhetővé tesz, mint például ISO_LOCAL_DATE és a ISO_ZONED_DATE_TIME szabványos formátumokhoz.

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);
    }
}

Két dátum összehasonlításához a modern API-ban hívja meg a következőt: isBefore, isAftervagy isEqualEzek a módszerek tisztábban olvashatók, mint compareTo és dolgozzon mindenkivel java.time osztály.

Szálbiztonság és a legjobb gyakorlatok a következőkhöz: Java Dátum és idő

Mindkét java.util.Date és a SimpleDateFormat megelőzi a modern egyidejűséget Java, és mindegyiknek ismert buktatói vannak. Kövesse az alábbi gyakorlatokat a dátumkezelés helyességének megőrzése érdekében az éles kódban:

  • A Date and Calendar helyett a java.time értéket részesítsd előnyben. Az új típusok megváltoztathatatlanok és szálbiztosak, valamint pontosabban modellezik a tartományt (dátumok időpontok nélkül, időpontok zónák nélkül stb.).
  • Ne ossz meg SimpleDateFormat formátumot több szálon. Az osztály belső elemzési állapotot tárol, és nem szálbiztos. Csomagolja be egy ThreadLocal, szinkronizáljon a példányon, vagy váltson erre: DateTimeFormatter.
  • Mindig adjon meg egy területi beállítást. A hónapok és napok nevei a JVM alapértelmezett területi beállításával változnak, ami olyan mintákat eredményez, mint például MMM és a EEE nem hordozható. Adjon meg explicit módon egy területi beállítást (például Locale.ENGLISH).
  • Légy egyértelmű az időzónákkal kapcsolatban. LocalDateTime nincs zónája, ezért konvertáljuk erre: ZonedDateTime or Instant amikor a pontos pillanat számít, különösen naplók, adatbázisoszlopok és hálózati hasznos adatok esetén.
  • Óvatosan konvertálj a két API között. Felhasználás date.toInstant(), Date.from(instant)és calendar.toInstant().atZone(zone) a hagyományos és a modern kód határán.
  • Az időbélyegek tárolása UTC-ben. Kitarts és transmit dátumok UTC-ként (egy Instant vagy egy ISO 8601 karakterlánc), és csak megjelenítéskor konvertáljon felhasználói zónává.

GYIK

A rendszerzónában lévő dátum és idő megadásához hívja meg a LocalDateTime.now() függvényt a java.time csomagból, vagy csak dátum megadásához a LocalDate.now() függvényt. Régebbi verziókon Java, használd a new java.util.Date() függvényt az aktuális pillanat lekéréséhez.

A java.util.Date az epoch óta eltelt milliszekundumban megadott pillanatot jelöli, és módosítható. A LocalDate egy naptári dátumot modellez idő vagy zóna nélkül, megváltoztathatatlan és szálbiztos, valamint egyértelműbb metódusokat kínál, mint például a plusDays és az isBefore.

Nem. A SimpleDateFormat megőrzi a módosítható elemzési állapotot, és hibás eredményeket ad, ha szálak között megosztjuk. Csomagold be egy ThreadLocal-ba, szinkronizáld a példányon, vagy válts DateTimeFormatterre, amely megváltoztathatatlan és biztonságos.

Pontosan az „éééé-HH-nn” karakterláncot kell megadni. A nagy HH a hónapot, a kis HH a percet jelöli. Teljes dátumhoz és időhöz használja az „éééé-HH-nn ÓÓ:pp:mm” formátumot. Mindig adjon meg területi beállítást, hogy a hónapnevek reproduálhatóak maradjanak.

Régi dátum esetén használd a compareTo függvényt, amely negatív, nulla vagy pozitív egész számot ad vissza. A java.time esetén hívd meg az isBefore, isAfter vagy isEqual függvényt LocalDate vagy Instant esetén. Mindkét megközelítés figyelembe veszi a kronológiai sorrendet.

Hívd meg a date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime() függvényt. Visszalépéshez használd a Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant()) függvényt. Válaszd ki explicit módon a zónát, amikor a pontos pillanat számít.

A napló- és dokumentumkorpuszokon betanított MI-modellek a minta karakterláncokból következtetik ki a valószínűsíthető mintát, és egy megfelelő DateTimeFormatter mintát adnak vissza. A gépi tanulással működő osztályozók a kétértelmű mezőket is megjelölik, például a hónap-nap vagy a nap-hónap sorrendet.

Igen. A GitHub Copilot DateTimeFormatter mintákat, ZonedDateTime konverziókat és JUnit területi beállításokra érzékeny kimenetet tesztel. RevA véglegesítés előtt tekintse meg az egyes javaslatokat a helyes mintabetűk, területi beállítások és időzónák tekintetében.

Foglald össze ezt a bejegyzést a következőképpen: