ADT datetime
Latihan membuat instruksi pembelajaran ADT DateTime dengan memanfaatkan ADT Time yang sebelumnya sudah diimplementasikan dalam bahasa pemrograman Rust.
Pembaca akan belajar membuat ADT DateTime yang memadukan tanggal (Date
) dan waktu (Time
) menjadi satu kesatuan. ADT ini dapat digunakan untuk mewakili momen tertentu secara lengkap, seperti 1 Januari 2025 14:30:15
.
Tujuan Pembelajaran
Setelah mempelajari materi ini, pembaca akan mampu:
Menjelaskan apa itu ADT DateTime dan kapan perlu menggunakannya.
Mengimplementasikan
struct DateTime
di Rust yang menggabungkanDate
danTime
.Mengimplementasikan operasi-operasi dasar: pembuatan, validasi, perbandingan, dan penambahan detik.
Menggunakan modul
datetime.rs
di dalammain.rs
sebagai driver.Mengenali edge cases seperti tanggal yang melewati akhir bulan atau tahun.
Prasyarat
Sudah memahami ADT Time (jam, menit, detik) dan cara kerjanya.
Memahami
struct
,impl
, dan penggunaan modul di Rust.Familiar dengan konsep validasi data (misalnya mengecek apakah bulan antara 1–12, hari sesuai jumlah hari dalam bulan).
Langkah-Langkah Tugas
1. Definisikan Modul datetime.rs
Kita akan membuat struct DateTime
yang terdiri dari Date
dan Time
.
Berikut implementasi sederhana yang mudah dipahami pemula:
// datetime.rs
use crate::time::Time;
#[derive(Debug, Clone)]
pub struct DateTime {
pub day: u32,
pub month: u32,
pub year: u32,
pub time: Time,
}
impl DateTime {
/// Membuat DateTime baru dengan validasi sederhana
pub fn new(day: u32, month: u32, year: u32, time: Time) -> Option<DateTime> {
if month >= 1 && month <= 12 && day >= 1 && day <= DateTime::days_in_month(month, year) {
Some(DateTime { day, month, year, time })
} else {
None // jika data tidak valid
}
}
/// Mendapatkan jumlah hari dalam bulan tertentu
fn days_in_month(month: u32, year: u32) -> u32 {
match month {
1 | 3 | 5 | 7 | 8 | 10 | 12 => 31,
4 | 6 | 9 | 11 => 30,
2 => {
if DateTime::is_leap_year(year) { 29 } else { 28 }
}
_ => 0
}
}
/// Mengecek tahun kabisat
fn is_leap_year(year: u32) -> bool {
(year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)
}
/// Membandingkan dua DateTime, mengembalikan true jika self lebih awal
pub fn is_earlier(&self, other: &DateTime) -> bool {
if self.year != other.year {
self.year < other.year
} else if self.month != other.month {
self.month < other.month
} else if self.day != other.day {
self.day < other.day
} else {
self.time.is_earlier(&other.time)
}
}
/// Menambahkan sejumlah detik ke DateTime (sederhana, tidak optimal)
pub fn add_seconds(&mut self, seconds: u32) {
let mut total_seconds = self.time.to_seconds() + seconds;
while total_seconds >= 86400 {
total_seconds -= 86400;
self.next_day();
}
self.time = Time::from_seconds(total_seconds);
}
/// Menambah satu hari ke DateTime
fn next_day(&mut self) {
if self.day < DateTime::days_in_month(self.month, self.year) {
self.day += 1;
} else {
self.day = 1;
if self.month < 12 {
self.month += 1;
} else {
self.month = 1;
self.year += 1;
}
}
}
}
2. Driver main.rs
Contoh sederhana penggunaan modul ini:
// main.rs
mod time;
mod datetime;
use time::Time;
use datetime::DateTime;
fn main() {
let time1 = Time::new(10, 0, 0).unwrap();
let time2 = Time::new(15, 30, 0).unwrap();
let dt1 = DateTime::new(28, 2, 2024, time1).unwrap();
let mut dt2 = DateTime::new(28, 2, 2024, time2).unwrap();
println!("DateTime 1: {:?}", dt1);
println!("DateTime 2: {:?}", dt2);
println!("Apakah dt1 lebih awal dari dt2? {}", dt1.is_earlier(&dt2));
dt2.add_seconds(3600); // tambah 1 jam
println!("DateTime 2 setelah ditambah 1 jam: {:?}", dt2);
}
Komentar:
unwrap()
digunakan agar kode singkat untuk pemula; jika invalid, program panic.add_seconds
memastikan jika lewat tengah malam, akan pindah hari.
Edge Cases yang Harus Dipertimbangkan
Tanggal tidak valid: 30 Februari, 31 April → harus ditolak.
Tahun kabisat: 29 Februari hanya valid pada tahun kabisat.
Penambahan detik melewati tengah malam → otomatis pindah hari.
Perbandingan tanggal berbeda tahun/bulan → pastikan urutan logika benar.
Pertanyaan Refleksi
Bagaimana jika ingin menambahkan fungsi
add_days(n)
yang menambah hari sekaligus?
Clue: Anda bisa memanggilnext_day()
sebanyakn
kali.Bagaimana Anda menangani input tanggal yang salah (misalnya 0 Januari atau 32 Desember)?
Clue: Fungsinew()
mengembalikanOption<DateTime>
agar program dapat memutuskan apakah membuat ulang input.Apa yang terjadi jika
add_seconds()
dipanggil dengan nilai yang sangat besar (misalnya setahun penuh dalam detik)?
Clue: Program masih akan bekerja, tapi akan melakukan loop harian berkali-kali. Bisa dipikirkan cara lebih efisien di tahap lanjut.
Referensi
Materi ADT dan implementasi modular diadaptasi dari:
Sekolah Teknik Elektro dan Informatika, Institut Teknologi Bandung. Materi Kuliah Struktur Data – ADT DateTime.