Acara-acara dunia nyata hampir selalu butuh tanggal dan jam sekaligus: rapat dimulai 15 Januari 2026 pukul 08:00, batas pengumpulan tugas 20 Maret pukul 23:59, jadwal pemutaran film malam hari. Menyimpan dua nilai terpisah — satu LocalDate dan satu LocalTime — membuka celah data tidak konsisten karena kedua nilai dapat diubah sendiri-sendiri. LocalDateTime menggabungkan keduanya menjadi satu objek yang sahih sebagai kesatuan, tetapi tetap tanpa zona waktu — murni “apa yang tertulis di kalender dinding”. Pada Chapter ini kita pelajari cara merakit, membaca kembali, memanipulasi, dan membandingkan LocalDateTime.
Membuat Objek LocalDateTime #
Ada empat jalur pembuatan yang lazim. Pertama, LocalDateTime.of(tahun, bulan, tanggal, jam, menit) mengisi seluruh komponen sekaligus. Kedua, kelebihan beban of(LocalDate, LocalTime) menggabungkan dua objek yang sudah ada. Ketiga, method atDate() milik LocalTime dan atTime() milik LocalDate merakit nilai dari salah satu sisi — bentuk yang enak dibaca saat kode berangkat dari salah satu komponen. Keempat, LocalDateTime.parse() membaca format ISO-8601 bawaan yang memisahkan tanggal dan waktu dengan huruf T:
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
public class MembuatLocalDateTime {
public static void main(String[] args) {
// Jalur 1: isi semua komponen langsung.
LocalDateTime rapat = LocalDateTime.of(2026, 1, 15, 8, 0);
// Jalur 2: gabungkan LocalDate + LocalTime yang sudah ada.
LocalDate tanggal = LocalDate.of(2026, 1, 15);
LocalTime jam = LocalTime.of(10, 30);
LocalDateTime kelas = LocalDateTime.of(tanggal, jam);
// Jalur 3: rakit dari salah satu sisi.
LocalDateTime lelang = jam.atDate(LocalDate.of(2026, 2, 20));
LocalDateTime konser = tanggal.atTime(19, 45);
// Jalur 4: parse format ISO-8601 bawaan.
LocalDateTime dariTeks = LocalDateTime.parse("2026-01-15T08:30");
System.out.println("rapat : " + rapat);
System.out.println("kelas : " + kelas);
System.out.println("lelang : " + lelang);
System.out.println("konser : " + konser);
System.out.println("dariTeks : " + dariTeks);
// Pecah kembali menjadi komponennya.
System.out.println("toLocalDate() : " + rapat.toLocalDate());
System.out.println("toLocalTime() : " + rapat.toLocalTime());
// Konstanta formatter ISO bawaan mencetak detik secara eksplisit.
System.out.println("ISO_LOCAL_DATE_TIME : " + rapat.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
}
}Output yang Dihasilkan:
rapat : 2026-01-15T08:00
kelas : 2026-01-15T10:30
lelang : 2026-02-20T10:30
konser : 2026-01-15T19:45
dariTeks : 2026-01-15T08:30
toLocalDate() : 2026-01-15
toLocalTime() : 08:00
ISO_LOCAL_DATE_TIME : 2026-01-15T08:00:00Mari kita telaah baris-baris kode di atas:
- Baris 8 (
LocalDateTime.of(2026, 1, 15, 8, 0)): seluruh komponen diisi langsung; sisanya (detik, nanodetik) bernilai nol. - Baris 12-13 (
of(tanggal, jam)): menggabungkan objekLocalDatedanLocalTimeyang telah dibuat — berguna saat kedua komponen datang dari variabel berbeda. - Baris 16-17 (
atDatedanatTime):LocalTime.atDate()menempelkan tanggal pada waktu,LocalDate.atTime()menempelkan waktu pada tanggal; hasilnya sama-samaLocalDateTime. - Baris 20 (
parse("2026-01-15T08:30")): hurufTadalah pemisah standar ISO-8601 antara bagian tanggal dan bagian waktu. - Baris 27-29:
toLocalDate()dantoLocalTime()memecah objek kembali menjadi komponen tanpa salinan ganda karena keduanya immutable.
Keluaran toString() memakai format ISO-8601 dengan pemisah T, misalnya 2026-01-15T08:00. Konstanta DateTimeFormatter.ISO_LOCAL_DATE_TIME mencetak versi yang lebih lengkap dengan detik eksplisit — 2026-01-15T08:00:00 — berguna saat bertukar data antar sistem.
Mengubah, Membandingkan, dan Mengukur Durasi #
Operasi penjumlahan dan pengurangan pada LocalDateTime mengikuti kalender sungguhan. Berbeda dari LocalTime yang berputar kembali ke 00:00, penjumlahan yang melewati tengah malam menggeser tanggal ke hari berikutnya. Method Duration.between() juga bekerja pada dua objek LocalDateTime dan menghasilkan durasi waktu fisik di antara keduanya:
import java.time.Duration;
import java.time.LocalDateTime;
public class ManipulasiLocalDateTime {
public static void main(String[] args) {
LocalDateTime mulai = LocalDateTime.of(2026, 1, 15, 8, 0);
// Semua operasi mengembalikan objek LocalDateTime yang baru.
LocalDateTime selesai = mulai.plusHours(5).plusMinutes(30);
LocalDateTime ulang = mulai.minusDays(7);
LocalDateTime majuJam = mulai.withHour(20);
System.out.println("mulai : " + mulai);
System.out.println("plus 5j 30m : " + selesai);
System.out.println("minus 7 hari : " + ulang);
System.out.println("withHour(20) : " + majuJam);
// Penjumlahan lintas tengah malam menggeser tanggal, bukan berputar.
LocalDateTime lewatTengahMalam = mulai.plusHours(20);
System.out.println("plus 20 jam : " + lewatTengahMalam);
LocalDateTime batas = LocalDateTime.of(2026, 1, 15, 12, 0);
System.out.println("isBefore(batas) : " + mulai.isBefore(batas));
System.out.println("compareTo(batas): " + mulai.compareTo(batas));
// Durasi fisik dihitung dari dua LocalDateTime.
Duration durasi = Duration.between(mulai, selesai);
System.out.println("Duration.between: " + durasi);
}
}Output yang Dihasilkan:
mulai : 2026-01-15T08:00
plus 5j 30m : 2026-01-15T13:30
minus 7 hari : 2026-01-08T08:00
withHour(20) : 2026-01-15T20:00
plus 20 jam : 2026-01-16T04:00
isBefore(batas) : true
compareTo(batas): -1
Duration.between: PT5H30MBaris 8-10 mengembalikan objek baru untuk tiga jenis perubahan: menggeser waktu lima setengah jam, memundurkan tujuh hari, dan mengganti komponen jam menjadi 20. Baris 17-18 menyoroti perbedaan penting dengan LocalTime: menambah 20 jam ke 08:00 tanggal 15 Januari melompat ke 04:00 tanggal 16 Januari. Baris 20-22 membandingkan dua nilai — isBefore mengembalikan true dan compareTo mengembalikan nilai negatif -1 karena 08:00 lebih awal daripada 12:00. Baris 25-26 menghasilkan Duration PT5H30M (lima jam tiga puluh menit dalam notasi ISO-8601) yang akan kita bedah tuntas pada bab Duration dan Period.
Kita kini memegang tanggal, waktu, dan gabungan keduanya — semuanya nilai “waktu dinding”. Pertanyaan berikutnya mengarah ke representasi paling objektif yang bisa dibandingkan lintas zona: pada momen persis apa suatu kejadian terjadi di garis waktu semesta? Instant menjawabnya dengan jam atom UTC, bintang bab berikutnya.
Referensi #
- Oracle: Class LocalDateTime (Java SE 25 API)
- Oracle: Package java.time (Java SE 25 API)
- dev.java: Date Time
Berkas Sumber
Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.
ManipulasiLocalDateTime.java
Unduh berkasimport java.time.Duration;
import java.time.LocalDateTime;
public class ManipulasiLocalDateTime {
public static void main(String[] args) {
LocalDateTime mulai = LocalDateTime.of(2026, 1, 15, 8, 0);
// Semua operasi mengembalikan objek LocalDateTime yang baru.
LocalDateTime selesai = mulai.plusHours(5).plusMinutes(30);
LocalDateTime ulang = mulai.minusDays(7);
LocalDateTime majuJam = mulai.withHour(20);
System.out.println("mulai : " + mulai);
System.out.println("plus 5j 30m : " + selesai);
System.out.println("minus 7 hari : " + ulang);
System.out.println("withHour(20) : " + majuJam);
// Penjumlahan lintas tengah malam menggeser tanggal, bukan berputar.
LocalDateTime lewatTengahMalam = mulai.plusHours(20);
System.out.println("plus 20 jam : " + lewatTengahMalam);
LocalDateTime batas = LocalDateTime.of(2026, 1, 15, 12, 0);
System.out.println("isBefore(batas) : " + mulai.isBefore(batas));
System.out.println("compareTo(batas): " + mulai.compareTo(batas));
// Durasi fisik dihitung dari dua LocalDateTime.
Duration durasi = Duration.between(mulai, selesai);
System.out.println("Duration.between: " + durasi);
}
}
MembuatLocalDateTime.java
Unduh berkasimport java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
public class MembuatLocalDateTime {
public static void main(String[] args) {
// Jalur 1: isi semua komponen langsung.
LocalDateTime rapat = LocalDateTime.of(2026, 1, 15, 8, 0);
// Jalur 2: gabungkan LocalDate + LocalTime yang sudah ada.
LocalDate tanggal = LocalDate.of(2026, 1, 15);
LocalTime jam = LocalTime.of(10, 30);
LocalDateTime kelas = LocalDateTime.of(tanggal, jam);
// Jalur 3: rakit dari salah satu sisi.
LocalDateTime lelang = jam.atDate(LocalDate.of(2026, 2, 20));
LocalDateTime konser = tanggal.atTime(19, 45);
// Jalur 4: parse format ISO-8601 bawaan.
LocalDateTime dariTeks = LocalDateTime.parse("2026-01-15T08:30");
System.out.println("rapat : " + rapat);
System.out.println("kelas : " + kelas);
System.out.println("lelang : " + lelang);
System.out.println("konser : " + konser);
System.out.println("dariTeks : " + dariTeks);
// Pecah kembali menjadi komponennya.
System.out.println("toLocalDate() : " + rapat.toLocalDate());
System.out.println("toLocalTime() : " + rapat.toLocalTime());
// Konstanta formatter ISO bawaan mencetak detik secara eksplisit.
System.out.println("ISO_LOCAL_DATE_TIME : " + rapat.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
}
}