1. LocalDate: data bez czasu i strefy czasowej
LocalDate — to po prostu data. Bez czasu, bez strefy czasowej, bez zbędnych kłopotów. Jak kartka w kalendarzu: 2025-06-01 — i tyle. Jeśli nie ma dla ciebie znaczenia, kiedy dokładnie następuje „północ” w różnych miastach, a potrzebujesz po prostu „1 czerwca 2025 roku” — użyj LocalDate.
Jak utworzyć LocalDate?
Sposobów jest kilka i wszystkie są proste i wygodne.
Bieżąca data
import java.time.LocalDate;
LocalDate today = LocalDate.now();
System.out.println(today); // Na przykład: 2025-06-01
Konkretna data
LocalDate birthday = LocalDate.of(1990, 12, 15);
System.out.println(birthday); // 1990-12-15
Można użyć liczb dla roku, miesiąca i dnia. Miesiąc — to liczba od 1 do 12 (styczeń — 1, grudzień — 12).
Parsowanie z ciągu znaków
LocalDate parsedDate = LocalDate.parse("2025-06-01");
System.out.println(parsedDate); // 2025-06-01
Ciąg musi być w formacie yyyy-MM-dd. Jeśli format się nie zgadza — zostanie zgłoszony wyjątek.
Pobieranie składników daty
U LocalDate są metody, które zwracają poszczególne części daty:
int year = today.getYear(); // 2025
int month = today.getMonthValue(); // 6 (czerwiec)
int day = today.getDayOfMonth(); // 1
System.out.println("Rok: " + year + ", miesiąc: " + month + ", dzień: " + day);
Jeśli chcesz poznać miesiąc słownie, użyj metody getMonth():
System.out.println(today.getMonth()); // JUNE
A jeśli potrzebny jest dzień tygodnia — metoda getDayOfWeek():
System.out.println(today.getDayOfWeek()); // SATURDAY
Praktyczny przykład
Kontynuujemy rozwijanie twojej edukacyjnej aplikacji konsolowej: teraz może ona składać użytkownikowi życzenia z okazji urodzin.
import java.time.LocalDate;
public class BirthdayApp {
public static void main(String[] args) {
LocalDate birthday = LocalDate.of(2000, 2, 29);
System.out.println("Data urodzenia: " + birthday);
System.out.println("Dzień tygodnia urodzenia: " + birthday.getDayOfWeek());
}
}
2. LocalTime: czas bez daty i strefy czasowej
LocalTime — to po prostu czas. Godziny, minuty, sekundy (a nawet nanosekundy). Ale bez daty! Jeśli trzeba przechowywać np. „godzinę otwarcia sklepu” lub „czas rozpoczęcia spotkania” bez powiązania z datą — to jest właściwa klasa.
Jak utworzyć LocalTime?
Bieżący czas
import java.time.LocalTime;
LocalTime now = LocalTime.now();
System.out.println(now); // Na przykład: 14:37:12.123456789
Konkretny czas
LocalTime lunchTime = LocalTime.of(13, 30); // 13:30:00
System.out.println(lunchTime);
Można dodać sekundy i nanosekundy:
LocalTime precise = LocalTime.of(8, 15, 30, 123_000_000); // 08:15:30.123
System.out.println(precise);
Parsowanie z ciągu znaków
LocalTime parsedTime = LocalTime.parse("14:30:00");
System.out.println(parsedTime); // 14:30
Pobieranie składników czasu
int hour = now.getHour();
int minute = now.getMinute();
int second = now.getSecond();
System.out.println("Godziny: " + hour + ", minuty: " + minute + ", sekundy: " + second);
Praktyczny przykład
Dodajmy do naszej aplikacji „zegar”:
import java.time.LocalTime;
public class ClockApp {
public static void main(String[] args) {
LocalTime current = LocalTime.now();
System.out.println("Teraz: " + current);
System.out.println("Godzina: " + current.getHour());
System.out.println("Minuta: " + current.getMinute());
}
}
3. LocalDateTime: data i czas bez strefy czasowej
LocalDateTime — to combo: data + czas, ale wciąż bez strefy czasowej. Na przykład „2025-06-01 14:30:00”. Jest to wygodne, gdy chcesz przechowywać moment w czasie, ale nie zależy ci na tym, gdzie na świecie będzie on odczytywany.
Jak utworzyć LocalDateTime?
Bieżąca data i czas
import java.time.LocalDateTime;
LocalDateTime now = LocalDateTime.now();
System.out.println(now); // Na przykład: 2025-06-01T14:30:15.123456789
Konkretna data i czas
LocalDateTime meeting = LocalDateTime.of(2025, 6, 1, 14, 30);
System.out.println(meeting); // 2025-06-01T14:30
Można dodać sekundy i nanosekundy:
LocalDateTime preciseMeeting = LocalDateTime.of(2025, 6, 1, 14, 30, 45, 123_000_000);
System.out.println(preciseMeeting); // 2025-06-01T14:30:45.123
Parsowanie z ciągu znaków
LocalDateTime parsed = LocalDateTime.parse("2025-06-01T14:30:00");
System.out.println(parsed); // 2025-06-01T14:30
Zwróć uwagę: litera T oddziela datę od czasu zgodnie ze standardem ISO.
Pobieranie składników
int year = now.getYear();
int month = now.getMonthValue();
int day = now.getDayOfMonth();
int hour = now.getHour();
int minute = now.getMinute();
System.out.println("Data: " + year + "-" + month + "-" + day + " Czas: " + hour + ":" + minute);
4. Typowe operacje na dacie i czasie
Teraz, gdy potrafimy tworzyć obiekty daty i czasu, nauczmy się robić z nimi coś pożytecznego.
Dodawanie i odejmowanie
Wszystkie trzy klasy (LocalDate, LocalTime, LocalDateTime) są niezmienne. To znaczy, że metody typu plusDays() lub minusMonths() zwracają nowy obiekt, nie zmieniając pierwotnego.
LocalDate
LocalDate today = LocalDate.now();
LocalDate tomorrow = today.plusDays(1);
LocalDate lastMonth = today.minusMonths(1);
System.out.println("Dzisiaj: " + today);
System.out.println("Jutro: " + tomorrow);
System.out.println("Miesiąc temu: " + lastMonth);
LocalTime
LocalTime now = LocalTime.now();
LocalTime inTenMinutes = now.plusMinutes(10);
System.out.println("Teraz: " + now);
System.out.println("Za 10 minut: " + inTenMinutes);
LocalDateTime
LocalDateTime start = LocalDateTime.of(2025, 6, 1, 14, 0);
LocalDateTime end = start.plusHours(2).minusMinutes(15);
System.out.println("Początek: " + start);
System.out.println("Koniec: " + end);
Porównywanie dat i czasu
Wszystkie klasy mają metody isBefore(), isAfter(), isEqual():
LocalDate birthday = LocalDate.of(2000, 2, 29);
LocalDate today = LocalDate.now();
if (today.isAfter(birthday)) {
System.out.println("Jesteś starszy niż ktoś, kto dopiero się urodził!");
}
LocalTime morning = LocalTime.of(8, 0);
LocalTime now = LocalTime.now();
if (now.isBefore(morning)) {
System.out.println("Jeszcze za wcześnie, żeby wstawać...");
} else {
System.out.println("Czas się budzić!");
}
Pobieranie bieżącej daty/czasu
Jak już widzieliśmy, metody now() zwracają bieżące wartości:
LocalDate date = LocalDate.now();
LocalTime time = LocalTime.now();
LocalDateTime dateTime = LocalDateTime.now();
5. Praktyka: przykłady i zadania
Przykład 1: Dzień tygodnia dla dowolnej daty
import java.time.LocalDate;
public class DayOfWeekApp {
public static void main(String[] args) {
LocalDate anyDate = LocalDate.of(2025, 12, 31);
System.out.println("31 grudnia 2025 roku — to " + anyDate.getDayOfWeek());
}
}
Przykład 2: Ile dni do Nowego Roku?
import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
public class DaysToNewYear {
public static void main(String[] args) {
LocalDate today = LocalDate.now();
LocalDate newYear = LocalDate.of(today.getYear() + 1, 1, 1);
long daysLeft = ChronoUnit.DAYS.between(today, newYear);
System.out.println("Do Nowego Roku zostało " + daysLeft + " dni!");
}
}
Przykład 3: Sprawdzenie, czy rok jest przestępny
import java.time.LocalDate;
public class LeapYearCheck {
public static void main(String[] args) {
LocalDate date = LocalDate.of(2025, 1, 1);
if (date.isLeapYear()) {
System.out.println(date.getYear() + " — rok przestępny!");
} else {
System.out.println(date.getYear() + " — rok nieprzestępny.");
}
}
}
Przykład 4: Różnica między dwoma czasami
import java.time.LocalTime;
import java.time.Duration;
public class TimeDifference {
public static void main(String[] args) {
LocalTime start = LocalTime.of(9, 0);
LocalTime end = LocalTime.of(17, 30);
Duration duration = Duration.between(start, end);
System.out.println("Dzień pracy trwa " + duration.toHours() + " godzin " +
(duration.toMinutes() % 60) + " minut.");
}
}
6. Typowe błędy
Błąd nr 1: Mylenie LocalDateTime i ZonedDateTime.
LocalDateTime nie zawiera informacji o strefie czasowej! Jeśli przechowujesz rozkłady lotów między krajami lub zdarzenia odbywające się w różnych strefach — używaj ZonedDateTime, w przeciwnym razie możesz uzyskać nieoczekiwane wyniki przy przenoszeniu danych między systemami.
Błąd nr 2: Używanie niewłaściwego formatu łańcucha do parsowania.
Na przykład próba sparsowania 01.06.2025 przez LocalDate.parse(). Domyślnie oczekiwany jest format 2025-06-01. Dla innych formatów potrzebny jest specjalny DateTimeFormatter (o tym w następnej lekcji!).
Błąd nr 3: Przekonanie, że metody typu plusDays() modyfikują obiekt.
Nie! Wszystkie obiekty są niezmienne. Metoda zwraca nowy obiekt, a stary pozostaje bez zmian.
Błąd nr 4: Używanie LocalTime do przechowywania czasu absolutnego.
LocalTime — wyłącznie do lokalnego czasu doby. Jeśli chcesz zapisać „moment w czasie”, użyj Instant lub ZonedDateTime.
Błąd nr 5: Zapominanie o numeracji miesięcy (1 — styczeń, 12 — grudzień).
W LocalDate.of(year, month, day) miesiące liczy się od 1 (a nie od 0, jak w niektórych innych językach lub starych API).
GO TO FULL VERSION