Tanggal, Waktu & Optional
Mengelola tanggal dan waktu dengan java.time (LocalDate, LocalDateTime, Duration, Period, format) serta menghindari NullPointerException dengan Optional.
Mengapa java.time?
Sebelum Java 8 orang memakai Date dan Calendar yang membingungkan dan tidak aman dipakai bersamaan. Sejak Java 8 ada paket java.time yang immutable (objek tidak pernah berubah; setiap operasi menghasilkan objek baru), jelas namanya, dan aman antar thread. Gunakan paket ini untuk semua kode baru.
| Class | Menyimpan | Contoh |
|---|---|---|
LocalDate | Tanggal saja | 2026-10-16 |
LocalTime | Jam saja | 14:30:00 |
LocalDateTime | Tanggal dan jam (tanpa zona waktu) | 2026-10-16T14:30 |
ZonedDateTime | Tanggal, jam, dan zona waktu | 2026-10-16T14:30+07:00[Asia/Jakarta] |
Instant | Satu titik waktu mesin (UTC) | untuk timestamp |
Duration | Selisih waktu dalam jam/menit/detik | PT2H30M |
Period | Selisih dalam tahun/bulan/hari | P1Y2M3D |
Membuat dan mengubah tanggal
import java.time.LocalDate;
LocalDate hariIni = LocalDate.now();
LocalDate lahir = LocalDate.of(2000, 5, 17); // tahun, bulan, hari
LocalDate dariTeks = LocalDate.parse("2026-12-31"); // format ISO yyyy-MM-dd
LocalDate besok = hariIni.plusDays(1);
LocalDate bulanDepan = hariIni.plusMonths(1);
LocalDate awalBulan = hariIni.withDayOfMonth(1);
System.out.println(hariIni.getYear()); // 2026
System.out.println(hariIni.getMonth()); // OCTOBER
System.out.println(hariIni.getDayOfWeek()); // FRIDAY
Penting: karena immutable, hariIni.plusDays(1) tidak mengubah hariIni. Kamu harus menangkap hasilnya ke variabel.
Membandingkan tanggal
LocalDate a = LocalDate.of(2026, 1, 1);
LocalDate b = LocalDate.of(2026, 6, 1);
a.isBefore(b); // true
a.isAfter(b); // false
a.equals(b); // false (jangan pakai ==)
Menghitung selisih
import java.time.Period;
import java.time.temporal.ChronoUnit;
Period p = Period.between(lahir, hariIni);
System.out.println(p.getYears() + " tahun " + p.getMonths() + " bulan");
long hari = ChronoUnit.DAYS.between(a, b); // 151
Duration d = Duration.between(jamMulai, jamSelesai);
System.out.println(d.toMinutes());
Memformat dan membaca teks
import java.time.format.DateTimeFormatter;
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("dd MMMM yyyy", new Locale("id", "ID"));
System.out.println(hariIni.format(fmt)); // 16 Oktober 2026
LocalDate d = LocalDate.parse("17-08-1945", DateTimeFormatter.ofPattern("dd-MM-yyyy"));
| Huruf | Arti |
|---|---|
yyyy | Tahun 4 digit |
MM / MMM / MMMM | Bulan angka / singkat / nama lengkap |
dd | Tanggal |
HH:mm:ss | Jam 24 jam, menit, detik (hh = format 12 jam) |
Hati-hati: MM adalah bulan, mm adalah menit. Tertukar adalah kesalahan klasik.
Optional: menghindari null
NullPointerException adalah error paling sering di Java. Optional<T> adalah kotak yang berisi nilai atau kosong, sehingga method bisa menyatakan terang-terangan "hasilnya mungkin tidak ada".
import java.util.Optional;
static Optional<String> cariEmail(String nama) {
if (nama.equals("Budi")) return Optional.of("budi@mail.com");
return Optional.empty();
}
Optional<String> hasil = cariEmail("Budi");
hasil.isPresent(); // true
hasil.get(); // "budi@mail.com" (hati-hati: error jika kosong)
cariEmail("Zaki").orElse("tidak ada"); // nilai cadangan
cariEmail("Budi").map(String::toUpperCase).orElse("-");
cariEmail("Budi").ifPresent(e -> System.out.println("Email: " + e));
cariEmail("Zaki").orElseThrow(() -> new IllegalArgumentException("Tidak ditemukan"));
| Method | Fungsi |
|---|---|
Optional.of(x) | Bungkus nilai (x tidak boleh null) |
Optional.ofNullable(x) | Bungkus nilai yang mungkin null |
Optional.empty() | Kotak kosong |
orElse(v) | Ambil isi, atau v jika kosong |
map(f) | Ubah isi jika ada |
ifPresent(aksi) | Jalankan aksi jika ada isi |
Aturan pakai Optional
- Pakai sebagai tipe kembalian method. Jangan jadikan field class atau parameter method.
- Hindari
get()tanpa memeriksa; pilihorElse,orElseThrow, atauifPresent. - Jangan pernah mengembalikan
nulldari method yang tipenya Optional.
Error umum
DateTimeParseException→ format teks tidak sesuai pola; periksa urutan dan huruf pola.DateTimeException: Invalid date 'FEBRUARY 30'→ tanggal tidak ada di kalender.NoSuchElementException: No value present→ memanggilget()pada Optional kosong.