๐ Menguasai Java Date and Time API: LocalDate, LocalTime, LocalDateTime, dan ZonedDateTime
API Tanggal dan Waktu Java (java.time
) merupakan peningkatan signifikan dari kelas java.util.Date
dan java.util.Calendar
yang lebih lama. Dirancang untuk mengatasi banyak kekurangan dari pendahulunya, API baru ini menawarkan pendekatan yang lebih intuitif, mudah digunakan, dan aman terhadap thread untuk menangani tanggal, waktu, dan zona waktu. Artikel ini memberikan panduan komprehensif tentang penggunaan kelas inti LocalDate
, LocalTime
, LocalDateTime
, dan ZonedDateTime
, yang dilengkapi dengan contoh praktis dan praktik terbaik untuk membantu Anda menguasai API modern ini.
Daftar Isi
- Pendahuluan pada Java Date and Time API
- Keuntungan Menggunakan Java Date and Time API
- LocalDate: Bekerja dengan Tanggal
- LocalTime: Bekerja dengan Waktu
- LocalDateTime: Bekerja dengan Tanggal dan Waktu
- ZonedDateTime: Bekerja dengan Tanggal dan Waktu dengan Zona Waktu
- Konversi Antara Kelas Tanggal dan Waktu
- Durasi dan Periode: Mengukur Waktu
- TemporalAdjusters: Manipulasi Tanggal Tingkat Lanjut
- Interoperabilitas dengan API Tanggal dan Waktu Legacy JDK
- Praktik Terbaik untuk Menggunakan Java Date and Time API
- Kesimpulan
Pendahuluan pada Java Date and Time API
Sebelum Java 8, kelas java.util.Date
dan java.util.Calendar
digunakan untuk menangani operasi tanggal dan waktu. Namun, API ini memiliki beberapa kekurangan:
- Dapat diubah (Mutable): Kelas
Date
dapat diubah, yang berarti nilainya dapat diubah setelah dibuat. Ini dapat menyebabkan masalah ketika berbagi instance tanggal di berbagai bagian kode. - Desain yang Buruk: Kelas
Calendar
rumit dan sulit digunakan. - Zona Waktu yang Buruk: Penanganan zona waktu tidak konsisten dan rawan kesalahan.
Java Date and Time API (java.time
), yang diperkenalkan di Java 8, mengatasi masalah-masalah ini dengan menyediakan API yang baru, lebih bersih, dan lebih mudah digunakan untuk bekerja dengan tanggal dan waktu.
Keuntungan Menggunakan Java Date and Time API
API modern ini menawarkan beberapa keuntungan signifikan:
- Tidak Dapat Diubah (Immutable): Kelas tanggal dan waktu tidak dapat diubah, memastikan bahwa nilainya tidak dapat diubah setelah dibuat. Ini membuat API lebih aman terhadap thread dan mengurangi risiko bug.
- Desain yang Jelas dan Intuitif: API dirancang dengan jelas dan intuitif, membuatnya lebih mudah dipelajari dan digunakan.
- Dukungan Zona Waktu yang Lebih Baik: API menyediakan dukungan yang kuat untuk zona waktu, termasuk kemampuan untuk menangani informasi zona waktu yang berbeda dan melakukan konversi zona waktu.
- Kemudahan Pengujian: Karena ketidakberubahan dan desain yang jelas, kelas-kelas ini lebih mudah diuji.
- ISO-8601: Format tanggal dan waktu default mematuhi standar ISO-8601.
LocalDate: Bekerja dengan Tanggal
Kelas LocalDate
mewakili tanggal tanpa waktu dan zona waktu. Ini berguna untuk menyimpan tanggal seperti tanggal lahir, tanggal acara, atau tanggal liburan.
Membuat Instance LocalDate
Anda dapat membuat instance LocalDate
dengan beberapa cara:
- Menggunakan tanggal saat ini:
- Menentukan tanggal secara eksplisit:
- Mengurai dari String:
Anda dapat menggunakan metode now()
untuk mendapatkan tanggal saat ini:
LocalDate today = LocalDate.now();
System.out.println("Tanggal Hari Ini: " + today); // Contoh: Tanggal Hari Ini: 2023-10-27
Anda dapat menggunakan metode of()
untuk membuat LocalDate
dengan menentukan tahun, bulan, dan hari:
LocalDate specificDate = LocalDate.of(2023, 12, 25); // Tahun, Bulan, Hari
System.out.println("Tanggal Spesifik: " + specificDate); // Contoh: Tanggal Spesifik: 2023-12-25
Atau menggunakan enum Month
:
LocalDate anotherSpecificDate = LocalDate.of(2024, Month.JANUARY, 1);
System.out.println("Tanggal Spesifik Lain: " + anotherSpecificDate); // Contoh: Tanggal Spesifik Lain: 2024-01-01
Anda dapat mengurai LocalDate
dari String
menggunakan metode parse()
. Format default adalah yyyy-MM-dd
:
LocalDate parsedDate = LocalDate.parse("2023-11-15");
System.out.println("Tanggal yang Diurai: " + parsedDate); // Contoh: Tanggal yang Diurai: 2023-11-15
Untuk format yang berbeda, gunakan DateTimeFormatter
:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy");
LocalDate formattedDate = LocalDate.parse("28/10/2023", formatter);
System.out.println("Tanggal yang Diformat: " + formattedDate); // Contoh: Tanggal yang Diformat: 2023-10-28
Mengakses Komponen Tanggal
Anda dapat mengakses berbagai komponen LocalDate
:
- Mendapatkan tahun:
getYear()
- Mendapatkan bulan:
getMonth()
(mengembalikan enumMonth
) ataugetMonthValue()
(mengembalikan angka bulan) - Mendapatkan hari dalam bulan:
getDayOfMonth()
- Mendapatkan hari dalam setahun:
getDayOfYear()
- Mendapatkan hari dalam seminggu:
getDayOfWeek()
(mengembalikan enumDayOfWeek
)
Contoh:
LocalDate date = LocalDate.of(2023, 10, 28);
int year = date.getYear(); // 2023
Month month = date.getMonth(); // OCTOBER
int dayOfMonth = date.getDayOfMonth(); // 28
DayOfWeek dayOfWeek = date.getDayOfWeek(); // SATURDAY
System.out.println("Tahun: " + year);
System.out.println("Bulan: " + month);
System.out.println("Hari dalam Bulan: " + dayOfMonth);
System.out.println("Hari dalam Seminggu: " + dayOfWeek);
Memodifikasi Tanggal
LocalDate
bersifat immutable, jadi metode modifikasi mengembalikan instance baru alih-alih memodifikasi yang sudah ada. Beberapa metode modifikasi umum meliputi:
plusYears(long yearsToAdd)
: Menambahkan tahun.plusMonths(long monthsToAdd)
: Menambahkan bulan.plusDays(long daysToAdd)
: Menambahkan hari.minusYears(long yearsToSubtract)
: Mengurangi tahun.minusMonths(long monthsToSubtract)
: Mengurangi bulan.minusDays(long daysToSubtract)
: Mengurangi hari.withYear(int year)
: Mengatur tahun.withMonth(int month)
: Mengatur bulan.withDayOfMonth(int dayOfMonth)
: Mengatur hari dalam bulan.
Contoh:
LocalDate date = LocalDate.of(2023, 10, 28);
LocalDate nextYear = date.plusYears(1); // 2024-10-28
LocalDate previousMonth = date.minusMonths(1); // 2023-09-28
LocalDate specificDay = date.withDayOfMonth(15); // 2023-10-15
System.out.println("Tahun Depan: " + nextYear);
System.out.println("Bulan Sebelumnya: " + previousMonth);
System.out.println("Hari Spesifik: " + specificDay);
Memformat dan Mengurai Tanggal
Anda dapat menggunakan kelas DateTimeFormatter
untuk memformat LocalDate
ke dalam String
dan mengurai String
menjadi LocalDate
.
Contoh:
LocalDate date = LocalDate.of(2023, 10, 28);
// Memformat menggunakan pola default
DateTimeFormatter defaultFormatter = DateTimeFormatter.ISO_LOCAL_DATE;
String formattedDateDefault = date.format(defaultFormatter); // 2023-10-28
System.out.println("Tanggal yang Diformat (Default): " + formattedDateDefault);
// Memformat menggunakan pola khusus
DateTimeFormatter customFormatter = DateTimeFormatter.ofPattern("dd/MM/yyyy");
String formattedDateCustom = date.format(customFormatter); // 28/10/2023
System.out.println("Tanggal yang Diformat (Kustom): " + formattedDateCustom);
// Mengurai String menjadi LocalDate
LocalDate parsedDate = LocalDate.parse("29/10/2023", customFormatter);
System.out.println("Tanggal yang Diurai: " + parsedDate); // 2023-10-29
Mengkueri Tanggal
Kelas LocalDate
menyediakan metode untuk mengkueri tanggal:
isLeapYear()
: Memeriksa apakah tahun ini adalah tahun kabisat.isBefore(LocalDate other)
: Memeriksa apakah tanggal ini sebelum tanggal lain.isAfter(LocalDate other)
: Memeriksa apakah tanggal ini setelah tanggal lain.isEqual(LocalDate other)
: Memeriksa apakah tanggal ini sama dengan tanggal lain.
Contoh:
LocalDate date1 = LocalDate.of(2024, 1, 1);
LocalDate date2 = LocalDate.of(2023, 1, 1);
boolean isLeap = date1.isLeapYear(); // true
boolean isBefore = date2.isBefore(date1); // true
boolean isAfter = date1.isAfter(date2); // true
System.out.println("Apakah tahun kabisat: " + isLeap);
System.out.println("Apakah sebelum: " + isBefore);
System.out.println("Apakah setelah: " + isAfter);
LocalTime: Bekerja dengan Waktu
Kelas LocalTime
mewakili waktu tanpa tanggal dan zona waktu. Ini berguna untuk menyimpan waktu seperti jam buka, jam kerja, atau waktu pertemuan.
Membuat Instance LocalTime
Anda dapat membuat instance LocalTime
dengan beberapa cara:
- Menggunakan waktu saat ini:
- Menentukan waktu secara eksplisit:
- Mengurai dari String:
Anda dapat menggunakan metode now()
untuk mendapatkan waktu saat ini:
LocalTime now = LocalTime.now();
System.out.println("Waktu Saat Ini: " + now); // Contoh: Waktu Saat Ini: 10:30:45.123
Anda dapat menggunakan metode of()
untuk membuat LocalTime
dengan menentukan jam, menit, dan opsional detik dan nanodetik:
LocalTime specificTime = LocalTime.of(14, 30); // Jam, Menit
System.out.println("Waktu Spesifik: " + specificTime); // Contoh: Waktu Spesifik: 14:30
LocalTime specificTimeWithSeconds = LocalTime.of(14, 30, 45); // Jam, Menit, Detik
System.out.println("Waktu Spesifik dengan Detik: " + specificTimeWithSeconds); // Contoh: Waktu Spesifik dengan Detik: 14:30:45
LocalTime specificTimeWithNanos = LocalTime.of(14, 30, 45, 123456789); // Jam, Menit, Detik, Nanodetik
System.out.println("Waktu Spesifik dengan Nanodetik: " + specificTimeWithNanos); // Contoh: Waktu Spesifik dengan Nanodetik: 14:30:45.123456789
Anda dapat mengurai LocalTime
dari String
menggunakan metode parse()
. Format default adalah HH:mm:ss.SSSSSSSSS
:
LocalTime parsedTime = LocalTime.parse("10:15");
System.out.println("Waktu yang Diurai: " + parsedTime); // Contoh: Waktu yang Diurai: 10:15
LocalTime parsedTimeWithSeconds = LocalTime.parse("10:15:30");
System.out.println("Waktu yang Diurai dengan Detik: " + parsedTimeWithSeconds); // Contoh: Waktu yang Diurai dengan Detik: 10:15:30
Untuk format yang berbeda, gunakan DateTimeFormatter
:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss");
LocalTime formattedTime = LocalTime.parse("15:45:59", formatter);
System.out.println("Waktu yang Diformat: " + formattedTime); // Contoh: Waktu yang Diformat: 15:45:59
Mengakses Komponen Waktu
Anda dapat mengakses berbagai komponen LocalTime
:
- Mendapatkan jam:
getHour()
- Mendapatkan menit:
getMinute()
- Mendapatkan detik:
getSecond()
- Mendapatkan nanodetik:
getNano()
Contoh:
LocalTime time = LocalTime.of(15, 30, 45, 123456789);
int hour = time.getHour(); // 15
int minute = time.getMinute(); // 30
int second = time.getSecond(); // 45
int nano = time.getNano(); // 123456789
System.out.println("Jam: " + hour);
System.out.println("Menit: " + minute);
System.out.println("Detik: " + second);
System.out.println("Nanodetik: " + nano);
Memodifikasi Waktu
LocalTime
bersifat immutable, jadi metode modifikasi mengembalikan instance baru alih-alih memodifikasi yang sudah ada. Beberapa metode modifikasi umum meliputi:
plusHours(long hoursToAdd)
: Menambahkan jam.plusMinutes(long minutesToAdd)
: Menambahkan menit.plusSeconds(long secondsToAdd)
: Menambahkan detik.plusNanos(long nanosToAdd)
: Menambahkan nanodetik.minusHours(long hoursToSubtract)
: Mengurangi jam.minusMinutes(long minutesToSubtract)
: Mengurangi menit.minusSeconds(long secondsToSubtract)
: Mengurangi detik.minusNanos(long nanosToSubtract)
: Mengurangi nanodetik.withHour(int hour)
: Mengatur jam.withMinute(int minute)
: Mengatur menit.withSecond(int second)
: Mengatur detik.withNano(int nano)
: Mengatur nanodetik.
Contoh:
LocalTime time = LocalTime.of(15, 30, 45);
LocalTime nextHour = time.plusHours(1); // 16:30:45
LocalTime previousMinute = time.minusMinutes(15); // 15:15:45
LocalTime specificSecond = time.withSecond(0); // 15:30:00
System.out.println("Jam Berikutnya: " + nextHour);
System.out.println("Menit Sebelumnya: " + previousMinute);
System.out.println("Detik Spesifik: " + specificSecond);
Memformat dan Mengurai Waktu
Anda dapat menggunakan kelas DateTimeFormatter
untuk memformat LocalTime
ke dalam String
dan mengurai String
menjadi LocalTime
.
Contoh:
LocalTime time = LocalTime.of(15, 30, 45);
// Memformat menggunakan pola default
DateTimeFormatter defaultFormatter = DateTimeFormatter.ISO_LOCAL_TIME;
String formattedTimeDefault = time.format(defaultFormatter); // 15:30:45
System.out.println("Waktu yang Diformat (Default): " + formattedTimeDefault);
// Memformat menggunakan pola khusus
DateTimeFormatter customFormatter = DateTimeFormatter.ofPattern("HH:mm:ss a");
String formattedTimeCustom = time.format(customFormatter); // 15:30:45 PM
System.out.println("Waktu yang Diformat (Kustom): " + formattedTimeCustom);
// Mengurai String menjadi LocalTime
LocalTime parsedTime = LocalTime.parse("16:45:00", DateTimeFormatter.ofPattern("HH:mm:ss"));
System.out.println("Waktu yang Diurai: " + parsedTime); // 16:45
LocalDateTime: Bekerja dengan Tanggal dan Waktu
Kelas LocalDateTime
mewakili tanggal dan waktu tanpa zona waktu. Ini hanyalah kombinasi dari LocalDate
dan LocalTime
.
Membuat Instance LocalDateTime
Anda dapat membuat instance LocalDateTime
dengan beberapa cara:
- Menggunakan tanggal dan waktu saat ini:
- Menentukan tanggal dan waktu secara eksplisit:
- Menggunakan instance LocalDate dan LocalTime:
- Mengurai dari String:
Anda dapat menggunakan metode now()
untuk mendapatkan tanggal dan waktu saat ini:
LocalDateTime now = LocalDateTime.now();
System.out.println("Tanggal dan Waktu Saat Ini: " + now); // Contoh: Tanggal dan Waktu Saat Ini: 2023-10-28T11:00:00.123
Anda dapat menggunakan metode of()
untuk membuat LocalDateTime
dengan menentukan tahun, bulan, hari, jam, menit, dan opsional detik dan nanodetik:
LocalDateTime specificDateTime = LocalDateTime.of(2023, 12, 25, 10, 30); // Tahun, Bulan, Hari, Jam, Menit
System.out.println("Tanggal dan Waktu Spesifik: " + specificDateTime); // Contoh: Tanggal dan Waktu Spesifik: 2023-12-25T10:30
LocalDateTime specificDateTimeWithSeconds = LocalDateTime.of(2023, 12, 25, 10, 30, 45); // Tahun, Bulan, Hari, Jam, Menit, Detik
System.out.println("Tanggal dan Waktu Spesifik dengan Detik: " + specificDateTimeWithSeconds); // Contoh: Tanggal dan Waktu Spesifik dengan Detik: 2023-12-25T10:30:45
LocalDateTime specificDateTimeWithNanos = LocalDateTime.of(2023, 12, 25, 10, 30, 45, 123456789); // Tahun, Bulan, Hari, Jam, Menit, Detik, Nanodetik
System.out.println("Tanggal dan Waktu Spesifik dengan Nanodetik: " + specificDateTimeWithNanos); // Contoh: Tanggal dan Waktu Spesifik dengan Nanodetik: 2023-12-25T10:30:45.123456789
Anda dapat menggunakan metode of()
untuk membuat LocalDateTime
dari instance LocalDate
dan LocalTime
:
LocalDate date = LocalDate.of(2023, 11, 10);
LocalTime time = LocalTime.of(16, 0);
LocalDateTime dateTime = LocalDateTime.of(date, time);
System.out.println("Tanggal dan Waktu dari LocalDate dan LocalTime: " + dateTime); // Contoh: Tanggal dan Waktu dari LocalDate dan LocalTime: 2023-11-10T16:00
Anda dapat mengurai LocalDateTime
dari String
menggunakan metode parse()
. Format default adalah yyyy-MM-ddTHH:mm:ss.SSSSSSSSS
:
LocalDateTime parsedDateTime = LocalDateTime.parse("2023-10-28T12:30");
System.out.println("Tanggal dan Waktu yang Diurai: " + parsedDateTime); // Contoh: Tanggal dan Waktu yang Diurai: 2023-10-28T12:30
Untuk format yang berbeda, gunakan DateTimeFormatter
:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss");
LocalDateTime formattedDateTime = LocalDateTime.parse("29/10/2023 17:45:00", formatter);
System.out.println("Tanggal dan Waktu yang Diformat: " + formattedDateTime); // Contoh: Tanggal dan Waktu yang Diformat: 2023-10-29T17:45
Mengakses Komponen Tanggal dan Waktu
Anda dapat mengakses komponen tanggal dan waktu dari LocalDateTime
:
- Mendapatkan LocalDate:
toLocalDate()
- Mendapatkan LocalTime:
toLocalTime()
- Mengakses komponen tanggal dan waktu individual (seperti pada LocalDate dan LocalTime).
Contoh:
LocalDateTime dateTime = LocalDateTime.of(2023, 11, 5, 18, 15, 30);
LocalDate date = dateTime.toLocalDate(); // 2023-11-05
LocalTime time = dateTime.toLocalTime(); // 18:15:30
int year = dateTime.getYear(); // 2023
int hour = dateTime.getHour(); // 18
System.out.println("Tanggal: " + date);
System.out.println("Waktu: " + time);
System.out.println("Tahun: " + year);
System.out.println("Jam: " + hour);
Memodifikasi Tanggal dan Waktu
LocalDateTime
bersifat immutable, jadi metode modifikasi mengembalikan instance baru alih-alih memodifikasi yang sudah ada. Anda dapat menggunakan metode yang sama seperti pada LocalDate
dan LocalTime
untuk memodifikasi tanggal dan waktu.
Contoh:
LocalDateTime dateTime = LocalDateTime.of(2023, 11, 5, 18, 15, 30);
LocalDateTime nextYear = dateTime.plusYears(1); // 2024-11-05T18:15:30
LocalDateTime previousHour = dateTime.minusHours(1); // 2023-11-05T17:15:30
LocalDateTime specificMinute = dateTime.withMinute(0); // 2023-11-05T18:00:30
System.out.println("Tahun Depan: " + nextYear);
System.out.println("Jam Sebelumnya: " + previousHour);
System.out.println("Menit Spesifik: " + specificMinute);
Memformat dan Mengurai Tanggal dan Waktu
Anda dapat menggunakan kelas DateTimeFormatter
untuk memformat LocalDateTime
ke dalam String
dan mengurai String
menjadi LocalDateTime
.
Contoh:
LocalDateTime dateTime = LocalDateTime.of(2023, 11, 5, 18, 15, 30);
// Memformat menggunakan pola default
DateTimeFormatter defaultFormatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
String formattedDateTimeDefault = dateTime.format(defaultFormatter); // 2023-11-05T18:15:30
System.out.println("Tanggal dan Waktu yang Diformat (Default): " + formattedDateTimeDefault);
// Memformat menggunakan pola khusus
DateTimeFormatter customFormatter = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss");
String formattedDateTimeCustom = dateTime.format(customFormatter); // 05/11/2023 18:15:30
System.out.println("Tanggal dan Waktu yang Diformat (Kustom): " + formattedDateTimeCustom);
// Mengurai String menjadi LocalDateTime
LocalDateTime parsedDateTime = LocalDateTime.parse("06/11/2023 19:00:00", customFormatter);
System.out.println("Tanggal dan Waktu yang Diurai: " + parsedDateTime); // 2023-11-06T19:00
ZonedDateTime: Bekerja dengan Tanggal dan Waktu dengan Zona Waktu
Kelas ZonedDateTime
mewakili tanggal dan waktu dengan zona waktu. Ini sangat penting ketika bekerja dengan aplikasi yang perlu mempertimbangkan zona waktu yang berbeda.
Membuat Instance ZonedDateTime
Anda dapat membuat instance ZonedDateTime
dengan beberapa cara:
- Menggunakan tanggal dan waktu saat ini dengan zona waktu:
- Menentukan tanggal, waktu, dan zona waktu secara eksplisit:
- Menggunakan instance LocalDateTime dan ZoneId:
- Mengurai dari String:
Anda dapat menggunakan metode now(ZoneId zone)
untuk mendapatkan tanggal dan waktu saat ini untuk zona waktu tertentu:
ZoneId zone = ZoneId.of("America/Los_Angeles");
ZonedDateTime now = ZonedDateTime.now(zone);
System.out.println("Tanggal dan Waktu Saat Ini di Los Angeles: " + now); // Contoh: Tanggal dan Waktu Saat Ini di Los Angeles: 2023-10-27T14:00:00.123-07:00[America/Los_Angeles]
Anda dapat menggunakan metode of()
untuk membuat ZonedDateTime
dengan menentukan tahun, bulan, hari, jam, menit, detik, nanodetik, dan zona waktu:
ZoneId zone = ZoneId.of("Europe/London");
ZonedDateTime specificDateTime = ZonedDateTime.of(2023, 12, 25, 10, 30, 0, 0, zone); // Tahun, Bulan, Hari, Jam, Menit, Detik, Nanodetik, ZoneId
System.out.println("Tanggal dan Waktu Spesifik di London: " + specificDateTime); // Contoh: Tanggal dan Waktu Spesifik di London: 2023-12-25T10:30Z[Europe/London]
Anda dapat membuat ZonedDateTime
dari instance LocalDateTime
dan ZoneId
:
LocalDateTime localDateTime = LocalDateTime.of(2023, 11, 10, 16, 0);
ZoneId zone = ZoneId.of("Asia/Tokyo");
ZonedDateTime zonedDateTime = ZonedDateTime.of(localDateTime, zone);
System.out.println("Tanggal dan Waktu di Tokyo: " + zonedDateTime); // Contoh: Tanggal dan Waktu di Tokyo: 2023-11-10T16:00+09:00[Asia/Tokyo]
Anda dapat mengurai ZonedDateTime
dari String
menggunakan metode parse()
. Anda harus menentukan format yang mencakup informasi zona waktu:
ZonedDateTime parsedDateTime = ZonedDateTime.parse("2023-10-28T12:30:00+02:00[Europe/Paris]");
System.out.println("Tanggal dan Waktu yang Diurai: " + parsedDateTime); // Contoh: Tanggal dan Waktu yang Diurai: 2023-10-28T12:30+02:00[Europe/Paris]
Untuk format yang berbeda, gunakan DateTimeFormatter
:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss ZZZZ");
ZonedDateTime formattedDateTime = ZonedDateTime.parse("29/10/2023 17:45:00 +0100", formatter);
System.out.println("Tanggal dan Waktu yang Diformat