Dátumkezelés Javában

Kategória: Java standard könyvtárak.

Date

A dátumkezelés a Java-ban - a fájlműveletekhez hasonlóan - lehetne átgondoltabb. Kezdetben a java.util.Date osztály feladata volt ennek a kezelése, amit ha paraméter nélkül példányosítunk, akkor az aktuális rendszeróra időpontját kapja értékül. A kiíráshoz viszont szükség van egy másik osztályra: a java.text.SimpleDateFormat-ra. Lássuk, hogyan tudjuk kiírni a pillanatnyi időpontot!

Date now = new Date();
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss zzz");
System.out.println(dateFormat.format(now));

Látható tehát, hogy ennek is nehézkes a használata, ráadásul van benne egy nagyon csúnya tervezési hiba is: úgy a Date mind a SimpleDateFormat nem szálbiztos. Természetszerűleg adná magát az, hogy egy programon belül létrehozunk egy globális SimpleDateFormat példányt, és azt használjuk mindenhol, csakhogy ez sajnos nehezen felderíthető hibákhoz vezet. Ezen kívül az időzónákat sem igazán kezeli.

Adott időpont megadásához a Date()-nek paraméterül a Unix rendszeridőt kell átadnunk, azaz az 1970. január 1-e óta eltelt másodpercek számát. Ez az írás pillanatában 1567178900. Ezen kívül lehetőég van az év, hónap, nap stb. beállítására és lekérdezésére, de már régóta nem javasolt a használatuk.

Az időpont megadásának nehézkessége miatt elég gyorsan megjelentek egyéb módszerek. Az egyik lehetőség a már említett SimpleDateFormat osztály parse() metódusa, pl:

Date birthDay = dateFormat.parse("1977-07-07 08:15:00 CET");

Ez java.text.ParseException-t dobhat, amit le kell kezelni.

Calendar

A másik módszer (és leginkább javasolt) a java.util.Calendar használata. Itt is egyesével be tudjuk állítani a ádtum elemeket, sőt, olyan dátum műveleteket is biztoít, mint adott számú elem (pl. nap, hónap) hozzáadása vagy kivonása. Lássunk erre is példát!

Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.YEAR, 2015);
calendar.add(Calendar.MONTH, 20);
Date fromCalendar = calendar.getTime();
System.out.println(dateFormat.format(fromCalendar));

A megadás egyszerűsítése lehetett a célja a GregorianCalendar-nak:

Calendar gregorian = new GregorianCalendar(2019, Calendar.AUGUST, 30, 17, 41, 32);

A hónapok sorszámozása 0-ról indul, tehát pl. az Augusztus a 7-es sorszámot viseli.

Dátumkezelés a Java 8-tól kezdve

Ezt a kuszaságot kívánta orvosolni a Java 8-ban megjelent újabb dátumkezelés. A vonatkozó osztályok a java.time csomagban vannak definiálva.

  • LocalDate: időzóna nélküli dátumot tudunk segítségével létrehozni, pl. LocalDate.now() (ma), LocalDate.of(2019, 8, 30) (év, hónap, nap, teljesen értelemszerűen, nem úgy mint az élelmiszereken) ill. LocalDate.parse("2019-08-30") (nem kell törődnünk a kivételkezeléssel).
  • LocalTime: hasonlóan helyi idő, pl. LocalTime.now(), LocalTime.of(16, 30), LocalTime.parse("16:30:00").
  • LocalDateTime: dátum és idő egyben, pl. LocalDateTime.now().
  • ZonedDateTime: dátum és idő zónainformációval, pl. ZonedDateTime.of(2019, 8, 30, 17, 41, 32, 0, ZoneId.of("UTC+2")).
  • Instant: adott nanoszekundum pontosságú időpillanat, pl. Instant.now().getNano().
  • DateTimeFormatter: az alapértelmezett kiírás teljesen korrekt, nem kell hozzá formázó, de ha nem tetszik, akkor választhatunk további ISO szabványok közül. Pl. DateTimeFormatter.ISO_LOCAL_DATE_TIME.format(LocalDateTime.now()).
  • Period: nap pontosságú periódus, pl. LocalDate.now().plus(Period.ofWeeks(4)).
  • Duration: nanoszekundom pontosságú periódus, pl. LocalTime.now().plus(Duration.ofSeconds(100)).

Mindezekhez járulnak a szokásos műveletek, pl. plusDays(). Lássunk egy teljes példát!

import java.time.*;
import java.time.format.DateTimeFormatter;
 
public class Java8DateExample {
 
    public static void main(String[] args) {
        System.out.println(LocalDate.parse("2019-08-30"));
        System.out.println(LocalTime.parse("16:30:00"));
        System.out.println(LocalDate.now());
        System.out.println(LocalTime.now());
        System.out.println(LocalDateTime.now());
        System.out.println(Instant.now().getNano());
        System.out.println(LocalDate.of(1977, 7, 7));
        System.out.println(ZonedDateTime.of(2019, 8, 30, 17, 41, 32, 0, ZoneId.of("UTC+2")));
        System.out.println(DateTimeFormatter.ISO_LOCAL_DATE_TIME.format(LocalDateTime.now()));
        System.out.println(LocalDate.now().plus(Period.ofWeeks(4)));
        System.out.println(LocalTime.now().plus(Duration.ofSeconds(100)));
 
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime dayAfterTomorrow = now.plusDays(2);
        System.out.println(now + ", " + dayAfterTomorrow);
    }
}
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License